home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Tool Chest / Development Tools & Languages / • Other Platforms / PCCTS 1.31 / Documentation / NOTES.newbie < prev    next >
Encoding:
Text File  |  1995-03-10  |  175.7 KB  |  4,391 lines  |  [TEXT/MPS ]

  1. 6 December 94
  2. Version 1.30 of pccts
  3.  
  4. =============================================================================
  5.     This help file is provided without warranty or guarantee of any kind.
  6. =============================================================================
  7.  
  8. This help file is available via anonymous FTP at:
  9.  
  10.         Node: everest.ee.umn.edu [128.101.144.112]
  11.         File: /pub/pccts/1.30/NOTES.newbie
  12.  
  13. Mirror sites for pccts:
  14.  
  15.      Europe:
  16.  
  17.         Node: ftp.th-darmstadt.de [130.83.55.75]
  18.         Directory: pub/programming/languages/compiler-compiler/pccts
  19.  
  20.                 According to the FAQ this is updated daily.
  21.  
  22.      Also:
  23.  
  24.         Node: ftp.uu.net
  25.         Directory: languages/tools/pccts
  26.  
  27. Pre-built binaries for pccts are available in:
  28.  
  29.         Node:        everest.ee.umn.edu [128.101.144.112]
  30.         Directory:   /pub/pccts/binaries/PC
  31.         Directory:   /pub/pccts/binaries/SGI
  32.         Directory:   /pub/pccts/binaries/Ultrix4.3
  33.                      etc.
  34.  
  35.                 Note:  There is no guarantee that these binaries will be
  36.                 up-to-date.  They are contributed by users of these machines
  37.                 rather than the pccts developers.
  38.  
  39. Contributed Files are in:
  40.  
  41.         Node:        everest.ee.umn.edu [128.101.144.112]
  42.         Directory:   /pub/pccts/contrib
  43.  
  44. Mail corrections or additions to moog@polhode.com
  45.  
  46. The format of NOTES.newbie has been changed to make it easier to look for
  47. changes from one version to the next using difference programs.
  48.  
  49.                                                                        Page 2
  50. ===============================================================================
  51. Miscellaneous
  52. -------------------------------------------------------------------------------
  53.                                                                       (Item 1)
  54. ##.  NEVER choose rule names, #token names, #lexclass names, #errclass
  55. names, etc. which coincide with the reserved words of your C or C++
  56. compiler. Be awake to name collisions with your favorite libraries
  57. and #include files.  One can only imagine the results of definitions like:
  58.  
  59.                 #token FILE "file"
  60.  
  61.                 const: "[0-9]*"
  62.                                                                       (Item 2)
  63. ##.  Tokens begin with uppercase characters. Rules begin with lowercase
  64. characters.
  65.                                                                       (Item 3)
  66. ##.  When passing the name of the start rule to the ANTLR macro don't
  67. forget to code the trailing function arguments:
  68.  
  69.         /* Not using ASTs  */   ANTLR (grammar(),stdin);
  70.         /* Using ASTs      */   ANTLR (grammar(&ASTroot),stdin);
  71.  
  72.         /* *** Wrong ***   */   ANTLR (grammar,stdin);
  73.                                                                       (Item 4)
  74. ##.  When you see a syntax error message that has quotation marks on
  75. separate lines:
  76.  
  77.         line 1: syntax error at "
  78.         " missing ID
  79.  
  80. that probably means that the offending element contains a newline.
  81.                                                                       (Item 5)
  82. ##.  Even if your C compiler does not support C++ style comments,
  83. you can use them in the *non-action* portion of the ANTLR source code.
  84. Inside an action (i.e.  <<...>> ) you have to obey the comment
  85. conventions of your compiler.
  86.                                                                       (Item 6)
  87. ##.  To place the C right shift operator (">>") inside an Antlr action
  88. ("<<...>>") precede it with a backslash: "\>>"  If you forget to do
  89. this you'll probably get the error message:
  90.  
  91.           warning: Missing <<; found dangling >>
  92.  
  93. No special action is required for the shift left operator.
  94.  
  95. This doesn't work with #lexaction or #header because the ">>" will be
  96. passed on to DLG which has exactly the same problem as Antlr.  The
  97. only workaround I found for these special cases was to place the following
  98. in an #include file "shiftr.h":
  99.  
  100.         #define SHIFTR  >>
  101.  
  102. where it is never seen by either Antlr or DLG.  Then I placed a #include
  103. "shiftr.h" in the #lexaction.
  104.                                                                        Page 3
  105.  
  106.                                                                       (Item 7)
  107. ##.  The C grammar distributed with pccts in pccts/lang/C has some
  108. shortcomings. It was written quite a while ago and has not been updated.
  109. It was written as an exercise, not as an end in itself.
  110.  
  111. The "proto" program does not invoke a C pre-processor. If your code
  112. needs the C pre-processor one must invoke it separately.  On my system
  113. one can use "cc -E ..." or "cc -P ..." to direct the output of the C
  114. pre-processor to the file specified by -o.
  115.  
  116. The C grammar does not know about #pragma which appears in the #include
  117. files of some systems.
  118.  
  119. There are some contributed versions of C grammars on node everest
  120. in /pub/pccts/contrib.  They are "pure" grammars and have no action
  121. routines.
  122.                                                                       (Item 8)
  123. ##.  To place main() in a ".c" file rather than a grammar file (".g")
  124. place:
  125.  
  126.                 #include "stdpccts.h"
  127.  
  128. before invoking the ANTRLR macro. Contributed by N.F. Ross.
  129.                                                                       (Item 9)
  130. ##.  ANTLR counts a line which is continued across a newline using
  131. the backslash convention as a single line.  For example:
  132.  
  133.         #header <<
  134.         #define abcd alpha\
  135.                 beta\
  136.                 gamma\
  137.                 delta
  138.         >>
  139.  
  140. This will cause line numbers in ANTLR error messages to be off by 3 compared
  141. to most text editors.
  142.                                                                       (Item 10)
  143. ##.  The Purdue Computer Science Department maintains a WWW directory
  144. which includes a pccts page:
  145.  
  146.         URL http://tempest.ecn.purdue.edu:8001/
  147.                                                                       (Item 11)
  148. ##.  In the discussions below one sometimes refers to "k=1" or "k>1".  The
  149. value of k is the number of tokens of lookahead.  However it is not
  150. necessarily the same as the value of the switch "-k" on Antlr's command
  151. line.  The number of tokens of lookahead maintained by Antlr/DLG is the
  152. maximum of the "-k" switch and the "-ck" switch.  Actually this is a
  153. half-truth.  Antlr rounds the maximum to the next higher power of 2 and
  154. calls this "LL_K".  Thus if one were to invoke Antlr with -k=1 -ck=3 the
  155. value of LL_K (and the number of buffers allocated for lookahead tokens)
  156. will actually be 4.
  157.                                                                        Page 4
  158.  
  159.                                                                       (Item 12)
  160. ##.  Suppose one wants to parse files that "include" other files.  The
  161. code in ANTLR (antlr.g) for handling #tokdefs statements demonstrates
  162. how this may be done.
  163.  
  164.     grammar:  ...
  165.  
  166.               | "#tokdefs"  QuotedTerm
  167.  
  168.                 <<{
  169.  
  170.                 zzantlr_state           st;     /* defined in antlr.h  */
  171.                 struct zzdlg_state      dst;    /* defined in dlgdef.h */
  172.                 FILE                    *f;
  173.  
  174.                 UserTokenDefsFile = mystrdup(LATEXT(1));
  175.                 zzsave_antlr_state(&st);
  176.                 zzsave_dlg_state(&dst);
  177.                 f = fopen(StripQuotes(LATEXT(1)),"r");
  178.                 if ( f==NULL ) {
  179.                     warn(eMsg1("cannot open token defs file '%s'",
  180.                                 LATEXT(1)+1));}
  181.                 else {
  182.                     ANTLRm( enum_file(), f, PARSE_ENUM_FILE);
  183.                     UserDefdTokens = 1;
  184.                 }
  185.                 zzrestore_antlr_state(&st);
  186.                 zzrestore_dlg_state(&dst);
  187.                 }>>
  188.  
  189. The code uses zzsave_antlr_state() and zzsave_dlg_state() to save the state
  190. of the current parse.  The ANTLRm macro specifies a starting rule for ANTLR
  191. of "enum_file" and starts DLG in the PARSE_ENUM_FILE state rather than the
  192. default state (which is the current state - whatever it might be).  Because
  193. enum_file() is called without any arguments it appears that enum_file() does
  194. not use ASTs nor pass back any attributes. Contributed by Terence J. Parr.
  195.                                                                       (Item 13)
  196. ##.  If an action becomes too large then it will overflow an ANTLR buffer
  197. ("... error: action buffer overflow: size 4000").
  198.  
  199. In cases where the code does NOT contain any references such as #[...],
  200. #(...), $xxx, #yyy  etc. (which requires substitution by Antlr) you can put
  201. the action in an include file and then place a #include in the action
  202. This is almost always effective with #lexaction and the main action.
  203.  
  204. Suggested by David Seidel (dseidel@delphi.com).
  205.  
  206. In other cases you must re-make Antlr with a larger value for ZZLEXBUFSIZE.
  207. The change can by made to the default value for ZZLEXBUFSIZE near line 73
  208. of pccts/h/antlr.h or by adding a statement like:
  209.  
  210.                 #define ZZLEXBUFSIZE 8192
  211.  
  212. to pccts/antlr/antlr.g in the #header.
  213.  
  214. Splitting an action of a rule into two smaller actions will not work if
  215. the second action needs to refer to zzlextext.
  216.                                                                        Page 5
  217.  
  218.                                                                       (Item 14)
  219. ##.  When one is using multiple input files (for example "a.g" and "b.g"
  220. to generate "a.c" and "b.c") the only way to place file scope information
  221. in b.c is to place it in #header of the first grammar file.  ANTLR won't
  222. allow file scope information to be copied from b.g into b.c using
  223. "<<...>>" notation.  If one did place a file scope action in the b.g, ANTLR
  224. would try to interpret it as the fail action of the last rule appearing in
  225. a.g. (the first grammar file).  The workaround is to #include b.c in
  226. another file which has your file scope declarations.  You'll probably
  227. need to #include "stdpccts.h" before your file scope definitions.
  228.                                                                       (Item 15)
  229. ##.  Multiple parsers can coexist in the same application through use of
  230. the #parser directive (in C output mode).  The #parser statement is not used
  231. with the ANTLR C++ output option because one can simply instantiate a new
  232. parser object.  The statement "#parser xyz" adds the prefix "xyz" to all
  233. rule names and many pccts defined names.  This is done as something of an
  234. afterthought by creating the #include file remap.h with definitions like
  235. the following:
  236.  
  237.         #define statement xyz_statement      /* a rule redefined        */
  238.         #define zztokenLA xyz_zztokenLA      /* pccts global redefined  */
  239.         #define AST xyz_AST                  /* pccts typedef redefined */
  240.         #define setwd1 xyz_setwd1            /* token test sets         */
  241.         #define zzerr_1 xyz_zzerr_1          /* error sets              */
  242.  
  243.  
  244.                                                                        Page 6
  245. ===============================================================================
  246. Section on switches and options
  247. -------------------------------------------------------------------------------
  248.                                                                       (Item 16)
  249. ##.  Invoking antlr or DLG with nothing else on the command line will
  250. cause them to print out a switch summary.
  251.                                                                       (Item 17)
  252. ##.  Don't forget about the ANTLR -gd option which provides a trace of
  253. rules which are triggered and exited.
  254.  
  255. The trace option can be useful in sometimes unexpected ways.  For example,
  256. by suitably defining the macros zzTRACEIN and zzTRACEOUT before the
  257. #include of "antlr.h" one can accumulate information on how often each
  258. rule is invoked.
  259.                                                                       (Item 18)
  260. ##.  When you want to inspect the code generated by ANTLR you may want to
  261. use the ANTLR -gs switch.  This causes ANTLR to test for a token being
  262. an element of  a lookahead set by using explicit tests with meaningful
  263. token names rather by using the faster bit oriented operations which are
  264. difficult to read.
  265.                                                                       (Item 19)
  266. ##.  When using the ANTLR -gk option you probably want to use the DLG -i
  267. option.  As far as I can tell neither option works by itself.
  268. Unfortunately they have different abbreviations so that one can't
  269. use the same symbol for both in a makefile.
  270.                                                                       (Item 20)
  271. ##.  When you are debugging code in the rule section and there is no
  272. change to the lexical scanner, you can avoid regeneration of scanner.c
  273. by using the ANTLR -gx option.  However some items from stdpccts.h
  274. can affect the scanner, such as -k -ck and the addition of semantic
  275. predicates - so this optimization should be used with a little care.
  276.                                                                       (Item 21)
  277. ##.  One cannot use an interactive scanner (ANTLR -gk option) with the
  278. ANTLR infinite lookahead and backtracking options (syntactic predicates).
  279.                                                                       (Item 22)
  280. ##.  If you want backtracking, but not the prefetching of characters and
  281. tokens that one gets with lookahead, then you might want to try using
  282. your own input routine and then using ANTLRs (input supplied by string)
  283. or ANTLRf (input supplied by function) rather than plain ANTLR which
  284. is used in most of the examples.
  285.  
  286. See Example 4 below for an example of an ANTLRf input function.
  287.                                                                       (Item 23)
  288. ##.  The format used in #line directive is controlled by the macro
  289.  
  290.                 #define LineInfoFormatStr "# %d \"%s\"\n"
  291.  
  292. which is defined in generic.h.  A change requires recompilation of ANTLR.
  293.  
  294. With Antlr switch -gl may cause Antlr to sometimes place #line directives
  295. in a column other than column 1 when processing semantic predicates.  The
  296. temporary workaround is to change the format string to:
  297.  
  298.                 #define LineInfoFormatStr "\n# %d \"%s\"\n"
  299.  
  300. This bug is present in version 1.23.
  301.                                                                       (Item 24)
  302. ##.  To make the lexical scanner case insensitive use the DLG -ci
  303. switch.  The analyzer does not change the text, it just ignores case
  304. when matching it against the regular expressions.
  305.  
  306. The problem in version 1.10 with the -ci switch is fixed in versions >= 1.20.
  307.                                                                        Page 7
  308.  
  309.                                                                       (Item 25)
  310. ##.  In order to use a different name for the mode.h file it is necessary
  311. to supply the new name using both the ANTLR -fm switch and the DLG -m switch.
  312. ANTLR does not generate mode.h, but it does generate #include statements
  313. which reference it.
  314.  
  315. ===============================================================================
  316. C++ Mode
  317. -------------------------------------------------------------------------------
  318.                                                                       (Item 26)
  319. ##.  Prior to version 1.23 when using backtracking (syntactic predicates)
  320. ANTLRtoken must have been explicitly derived from ANTLRCommonBacktrackingToken
  321. rather than ANTLRCommonToken.  With version 1.23 Antlr generates a typedef for
  322. the base class so that the correct one is automatically chosen.
  323.  
  324.                                                                        Page 8
  325. ===============================================================================
  326. Section on #token, #tokclass, #tokdef #errclass (but not #lexclass)
  327. -------------------------------------------------------------------------------
  328.                                                                       (Item 27)
  329. ##.  If you can't figure out what the DLG lexer is doing try inserting
  330. the following code near line 434 of pccts/h/dlgauto.h:
  331.  
  332.         #include "string.h"
  333.  
  334. old-->  (*actions[accepts[state]])();           /* invokes action routine */
  335.  
  336. add-->  {char zzcharstring[]="?";               /* put zzchar in string   */
  337.          zzcharstring[0]=zzchar;
  338.  
  339.          printf ("\nNLA=%s zzlextext=(%s) zzchar=(%s) %s\n",
  340.                 zztokens[NLA],                  /* token name             */
  341.                 (strcmp (zzlextext,"\n")==0 ? "newline" : zzlextext),
  342.                                                 /* render \n as "newline" */
  343.                 (strcmp (zzcharstring,"\n")==0 ? "newline" : zzcharstring),
  344.                                                 /* render \n as "newline" */
  345.                 (zzadd_erase==1 ? "zzskip()" :  /* called zzskip() ?      */
  346.                  zzadd_erase==2 ? "zzmore()" :  /* called zzmore() ?      */
  347.                                  ""));          /* none of the above      */
  348.         };
  349.  
  350.     NLA:        the the token number of the token just identified
  351.                 this is a macro
  352.     zztokens:   array indexed by token number giving the token name
  353.     zzlextext:  the text of the token just identified
  354.     zzchar:     the lookahead character
  355.                                                                       (Item 28)
  356. ##.  To gobble up everything to a newline use: "~[\n]*".
  357.                                                                       (Item 29)
  358. ##.  To match any single character use: "~[]".
  359.                                                                       (Item 30)
  360. ##.  The char * array "zztokens" in err.c contains the text for the name of
  361. each token (indexed by the token number).  This can be extremely useful
  362. for debugging and error messages.
  363.                                                                       (Item 31)
  364. ##.  If a #token symbol is spelled incorrectly in a rule it will not be
  365. reported by ANTLR unless the ANTLR -w2 option is set.  ANTLR will assign
  366. it a new  #token number which, of course, will never be matched.  Look at
  367. token.h for misspelled terminals or inspect "zztokens[]" in err.c.
  368.                                                                       (Item 32)
  369. ##.  If you happen to define the same #token name twice (perhaps
  370. because of inadvertent duplication of a name) you will receive no
  371. error messages from ANTLR or DLG.  ANTLR will simply use the later
  372. definition and forget the earlier one.  Using the ANTLR -w2 option
  373. does not change this behavior.
  374.                                                                       (Item 33)
  375. ##.  One cannot continue a regular expression in a #token statement across
  376. lines.  If one tries to use "\" to continue the line the lexical analyzer
  377. will think you are trying to match a newline character.
  378.                                                                       (Item 34)
  379. ##.  The escaped literals in #token regular expressions are not identical
  380. to the ANSI escape sequences.  For instance "\v" will yield a match
  381. for "v", not a vertical tab.
  382.  
  383.         \t      \n      \r      \b      - the only escaped letters
  384.                                                                        Page 9
  385.  
  386.                                                                       (Item 35)
  387. ##.  In #token regular expressions spaces and tabs which are
  388. not escaped are ignored - thus making it easy to add white space to
  389. a regular expression.
  390.  
  391.         #token  symbol  "[a-z A-Z] [a-z A-Z 0-9]*"
  392.                                                                       (Item 36)
  393. ##.  You can achieve a limited form of one character lookahead in the
  394. #token statement action by using zzchar which contains the character
  395. following the regular expression just recognized.  See Example 11.
  396.                                                                       (Item 37)
  397. ##.  The regular expressions appearing in #errclass declarations must
  398. be unique.
  399.                                                                       (Item 38)
  400. ##.  You cannot supply an action (even a null action) for a #token
  401. statement without a regular expression. You'll receive the message:
  402.  
  403.         warning: action cannot be attached to a token name
  404.                 (...token name...); ignored
  405.  
  406. This is a minor problem when the #token is created for use with
  407. attributes or ASTs nodes and has no regular expression:
  408.  
  409.         #token  CAST_EXPR
  410.         #token  SUBSCRIPT_EXPR
  411.         #token  ARGUMENT_LIST
  412.  
  413.         <<
  414.         ... Code related to parsing
  415.         >>
  416.  
  417. ANTLR assumes the code block is the action associated with the #token
  418. immediately preceding it.  It is not obvious what the problem is because
  419. the line number referenced is the END of the code block (">>") rather
  420. than the beginning.  My solution is to follow such #token statements
  421. with a #token which does have a regular expression (or a rule).
  422.                                                                       (Item 39)
  423. ##.  Since the lexical analyzer wants to find the longest possible string
  424. that matches a regular expression, it is probably best not to use expressions
  425. like "~[]*" which will gobble up everything to the end-of-file.
  426.                                                                       (Item 40)
  427. ##.  Calls to zzskip() and zzmore() should appear only in #token actions
  428. (or in code called from #token actions).  They don't belong in the actions
  429. of rules.  Routine zzskip() causes DLG to throw away the text just
  430. collected and to start looking for another regular expression.  Routine
  431. zzmore() tells DLG that the token is not complete and to look for more
  432. text.  They are purely lexical actions.
  433.                                                                       (Item 41)
  434. ##.  The lexical routines zzmode(), zzskip(), and zzmore() do NOT work like
  435. coroutines.  Basically, all they do is set status bits or fields in a
  436. structure owned by the lexical analyzer and then return immediately.  Thus it
  437. is OK to call these routines anywhere from within a lexical action.  You
  438. can even call them from within a subroutine called from a lexical action
  439. routine.
  440.  
  441. See Example 5 below for routines which maintain a stack of modes.
  442.                                                                        Page 10
  443.  
  444.                                                                       (Item 42)
  445. ##.  When a string is matched by two #token regular expressions of equal
  446. length, the lexical analyzer will choose the one which appears first in
  447. the source code.  Thus more specific regular expressions should appear
  448. before more general ones:
  449.  
  450.         #token  HELP    "help"         /*  should appear before "symbol" */
  451.         #token  symbol  "[a-zA-Z]*"    /*  should appear after keywords  */
  452.  
  453. Some of these may be caught by using the DLG switch -Wambiguity.
  454. Consider the following grammar:
  455.  
  456.         #header <<
  457.         #include "charbuf.h"
  458.         >>
  459.         <<
  460.         int main() {
  461.                 ANTLR (statement(),stdin);
  462.                 return 0;
  463.         }
  464.         >>
  465.  
  466.         #token  WhiteSpace      "[\ \t]"        <<zzskip();>>
  467.         #token  ID              "[a-z A-Z]*"
  468.         #token  HELP            "HELP"
  469.  
  470.         statement
  471.                 : HELP "@"      <<printf("token HELP\n");>>    /* a1 */
  472.                 | "inline" "@"  <<printf("token inline\n");>>  /* a2 */
  473.                 | ID "@"        <<printf("token ID\n");>>      /* a3 */
  474.                 ;
  475.  
  476. Is an in-line regular expression treated any differently than a regular
  477. expression appearing in a #token statement ?  No! ANTLR/DLG does *NOT*
  478. check for a match to "inline" (line a2)  before attempting a match to the
  479. regular expressions defined by #token statements. The first two
  480. alternatives ("a1" and "a2") will NEVER be matched. All of this will be
  481. clear from examination of the file "parser.dlg".
  482.  
  483. Another way of looking at this is to recognize that the conversion of
  484. character strings to tokens takes place in DLG, not Antlr, and that all
  485. that is happening with an in-line regular expression is that Antlr is
  486. allowing you to define a token's regular expression in a more convenient
  487. fashion - not changing the fundamental behavior.
  488.  
  489. If one builds the example above using the DLG switch -Wambiguity one gets
  490. the message:
  491.  
  492.         dlg warning: ambigious regular expression  3  4
  493.         dlg warning: ambigious regular expression  3  5
  494.  
  495.                                                                        Page 11
  496. The numbers which appear in the DLG message refer to the assigned token
  497. numbers.  Examine the array zztokens[] in err.c to find the regular
  498. expression which corresponds to the token number reported by DLG.
  499.  
  500.         ANTLRChar *zztokens[6]={
  501.                 /* 00 */        "Invalid",
  502.                 /* 01 */        "@",
  503.                 /* 02 */        "WhiteSpace",
  504.                 /* 03 */        "ID",
  505.                 /* 04 */        "HELP",
  506.                 /* 05 */        "inline"
  507.         };
  508.  
  509. One can also look at the file "scan.c" in which action 4 would
  510. appear in the function "static void act4() {...}".
  511.  
  512. The best advice is to follow the example of the Master, TJP, and place
  513. things like #token ID at the end of the grammar file.
  514.                                                                       (Item 43)
  515. ##.  The DLG lexical analyzer is not able to backtrack.  Consider the
  516. following example:
  517.  
  518.         #token          "[\ \t]*]       <<zzskip();>>
  519.         #token ELSE     "else"
  520.         #token ELSEIF   "else [\ \t]* if"
  521.         #token STOP     "stop"
  522.  
  523. with input:
  524.  
  525.         else stop
  526.  
  527. When DLG gets to the end of "else" it realizes that the spaces will allow
  528. it to match a longer string than "else" by itself. So DLG starts to accept
  529. the spaces. When DLG gets to the initial "s" in "stop" it realizes it has
  530. gone too far - but it can't backtrack.  It passes back an error status to
  531. ANTLR which (normally) prints out something like:
  532.  
  533.                 invalid token near line 1 (text was 'else ') ...
  534.  
  535. There is an "extra" space between the "else" and the closing single quote
  536. mark.
  537.  
  538. This problem is not detected by the DLG option -Wambiguity.
  539.                                                                        Page 12
  540.  
  541.                                                                       (Item 44)
  542. ##. If only one character of lookahead is necessary to distinguish the two
  543. tokens one can use zzchar.  This is an excerpt from Example 11:
  544.  
  545. #token Range    ".."
  546. #token Int      "[0-9]*"
  547. #token Float    "[0-9]*.[0-9]*"
  548.         <<if (*zzendexpr == '.' && /* might use more complex test */
  549.               zzchar == '.') {
  550.                 NLA=Int;
  551.                 zzmode(LC_Range);
  552.           };
  553.         >>
  554.  
  555. In this excerpt, a Range can be distinguished from a Float by seeing
  556. if the first "." is followed by a second ".".
  557.  
  558. If more than one character of lookahead is necessary and it appears
  559. difficult to solve using #lexclass, semantic predicates, or other
  560. mechanisms you might want to consider using the University of California
  561. Berkeley flex, which is a super-set of lex.  An example of how to use
  562. flex with Antlr is available on everest in /pub/pccts/contrib.
  563.                                                                       (Item 45)
  564. ##.  In converting a long list of tokens appearing in a rule to use #tokclass
  565. I simply replaced the rule, in situ, with the #tokclass directive and did a
  566. global replace of the rule name with a new name in which the first letter
  567. was capitalized.  It took me a while to realize that the ANTLR message:
  568.  
  569.         xxx.g, line 123: warning: redefinition of tokclass or conflict
  570.                  w/token 'Literal'; ignored
  571.  
  572. meant that I had used the #tokclass "Literal" before it was defined.
  573. Only rules, not tokens, can be used in forward references.  The problem
  574. was fixed by moving the #tokclass statement up to the #token section of
  575. the file.
  576.                                                                       (Item 46)
  577. ##.  The char * variable zzbegexpr and zzendexpr point to the start and end
  578. of the string last matched by a regular expression in a #token statement.
  579.  
  580. However, the char array pointed to by zzlextext may be larger than the
  581. string pointed to by zzbegexpr and zzendexpr because it includes substrings
  582. accumulated through the use of zzmore().
  583.                                                                       (Item 47)
  584. ##.  The preprocessor symbol ZZCOL in the lexical scanner controls the
  585. update of column information. This doesn't cause the zzsyn() routine to
  586. report the position of tokens causing the error.  You'll still have to
  587. write that yourself.  The problem, I think, is that, due to look-ahead,
  588. the value of zzendcol will not be synchronized with the token causing the
  589. error, so that the problem becomes non-trivial.
  590.                                                                       (Item 48)
  591. ##.  If you want to use ZZCOL to keep track of the column position
  592. remember to adjust zzendcol in the lexical action when a character is not
  593. one print position wide (e.g. tabs or non-printing characters).
  594.                                                                       (Item 49)
  595. ##.  The column information (zzbegcol and zzendcol) is not immediately
  596. updated if a token's action routine calls zzmore(). In cases where
  597. zzmore() is central the lexical analysis (e.g. Example 8 which combines
  598. whitespace with the token that follows) it may be better to write ones own
  599. column position routine rather than using the pccts supplied code.
  600.                                                                        Page 13
  601.  
  602.                                                                       (Item 50)
  603. ##.  Variables zzbegcol and zzendcol are the column positions of the
  604. token just analyzed by DLG.  When LL_K=1 this is generally the same as the
  605. token just analyzed by Antlr. When  LL_K > 1 the information in zzbegcol and
  606. zzendcol will be several tokens ahead of where Antlr is and thus will
  607. give misleading information.
  608.                                                                       (Item 51)
  609. ##.  In version 1.00 it was common to change the token code based on
  610. semantic routines in the #token actions.  With the addition of semantic
  611. predicates in 1.06 this technique is now frowned upon.
  612.  
  613. Old style:
  614.  
  615.         #token TypedefName
  616.         #token ID  "[a-z A-Z]*"
  617.                 <<{if (isTypedefName(LATEXT(1))) NLA=TypedefName;};>>
  618.  
  619. New Style:
  620.  
  621.         #token ID  "[a-z A-Z]*"
  622.  
  623.         typedefName : <<LA(1)==ID ? isTypedefName(LATEXT(1)) : 1>> ID;
  624.  
  625. The "old" technique is appropriate for making LEXICAL decisions based on
  626. the input: for instance treating whitespace differently in different
  627. contexts.  The reason why the "new" style is especially important is that
  628. with infinite lookahead, of which guess mode is one case, it is not
  629. possible to make semantic decisions in the lexer because the parsing
  630. doesn't even begin until the lexing is complete.
  631.  
  632. See the section on semantic predicates for a longer explanation.
  633.                                                                        Page 14
  634.  
  635.                                                                       (Item 52)
  636. ##.  DLG has no operator like grep's "^" which anchors a pattern to the
  637. beginning of a line.  One can use tests based on zzbegcol only if column
  638. information is selected (#define ZZCOL) AND one is NOT using infinite
  639. lookahead mode (syntactic predicates).  A technique which does not depend
  640. on zzbegcol is to look for the newline character and then enter a special
  641. #lexclass.
  642.  
  643. Consider the problem of recognizing lines which have a "!" as the first
  644. character of a line.  A possible solution suggested by Doug Cuthbertson
  645. is:
  646.  
  647.     #token "\n"          <<zzline++; zzmode(BEGIN_LINE);>>
  648.  
  649. *** or ***
  650.  
  651.     #token "\n"          <<zzline++;
  652.                            if (zzchar=='!') zzmode(BEGIN_LINE);>>
  653.  
  654.     #lexclass BEGIN_LINE
  655.     #token BANG "!"      <<zzmode(START);>>
  656.     #token      "~[]"    <<zzmode(START); zzmore();>>
  657.  
  658. When a newline is encountered the #lexclass BEGIN_LINE is entered.  If
  659. the next character is a "!" it returns the token "BANG" and returns
  660. to #lexclass START.  If the next character is anything else it calls
  661. zzmore to accumulate additional characters for the token and, as before,
  662. returns to #lexclass START.  (The order of calls to zzmode() and zzmore()
  663. is not significant).
  664.  
  665. There are two limitations to this.
  666.  
  667. a. If there are other single character tokens which can appear in the first
  668. column then using zzmore() won't be sufficient to work around the problem
  669. because the entire (one character) token has already been consumed.  Thus
  670. all single character tokens which can appear in column 1 must appear in
  671. both #lexclass START and #lexclass BEGIN_LINE.
  672.  
  673. b. The first character of the first line is not preceded by a newline.
  674. thus DLG will be starting in the wrong state.  Thus you might want to rename
  675. "BEGIN_LINE" to "START" and "START" to "NORMAL".
  676.  
  677. Another solution is to use ANTLRf (input from a function) to insert
  678. your own function to do the kind of lexical processing which is difficult
  679. to express in DLG.
  680.  
  681. In 1.20 the macro ANTLRm was added.  it is similar to ANTLR, but has an
  682. extra argument which allows one to specify the lexical class which is
  683. passed to zzmode() to specify the initial #lexclass state of DLG.
  684.                                                                       (Item 53)
  685. ##.  In version 1.10 there were problems using 8 bit characters with DLG.
  686. Versions >= 1.20 of ANTLR/DLG work with 8 bit character sets when they are
  687. compiled in a mode in which char variables are by default unsigned (the
  688. g++ option "-funsigned-char"). This should be combined with  a call to
  689. setlocale (LC_ALL,"") to replace the default locale of "C" with the user's
  690. native locale.  This is system dependent - it works with Unix systems but
  691. not DOS.  Contributed by Ulfar Erlingsson (ulfarerl@rhi.hi.is).
  692.  
  693. See Example 4 below.
  694.                                                                       (Item 54)
  695. ##.  Example 8 demonstrates how to pass whitespace through DLG for
  696. such applications as pretty-printers.
  697.                                                                        Page 15
  698.  
  699.                                                                       (Item 55)
  700. ##.  In version 1.30 it will be possible to test whether a token is
  701. a member of a #tokclass named "A" with a statement like the following:
  702.  
  703.         if (set_el(LA(1),A_set)) {...}
  704.  
  705.                 set_el(unsigned,set) is defined in pccts/support/set/set.c
  706.  
  707. Until that time a workaround is to define all members of a #tokclass
  708. together so as to take advantage of the knowledge that Antlr assigns
  709. #token numbers sequentially.  With that information one can write:
  710.  
  711.         if (LA(1) >= first_token_in_tokclass_A &&
  712.             LA(1) <= last_token_in_tokclass_A) {...}
  713.  
  714. (kenw@ihs.com).
  715.  
  716.                                                                        Page 16
  717. ===============================================================================
  718. Section on #lexclass
  719. -------------------------------------------------------------------------------
  720.                                                                       (Item 56)
  721. ##.  Example 10 gives a simple illustration of #lexclass.
  722.                                                                       (Item 57)
  723. ##.  Special care should be taken when using "in-line" regular expressions
  724. in rules if there are multiple lexical classes #lexclass).  ANTLR will
  725. place such regular expressions in the last lexical class defined.  If
  726. the last lexical class was not START you may be surprised.
  727.  
  728.         #lexclass START
  729.         ....
  730.         #lexclass COMMENT
  731.         ....
  732.  
  733.         inline_example: symbol "=" expression
  734.  
  735.                 This will place "=" in the #lexclass COMMENT (where
  736.                 it will never be matched) rather than the START #lexclass
  737.                 where the user meant it to be.
  738.  
  739. Since it is okay to specify parts of the #lexclass in several pieces
  740. it might be a good idea when using #lexclass to place "#lexclass START"
  741. just before the first rule - then any in-line definitions of tokens
  742. will be placed in the START #lexclass automatically.
  743.  
  744.         #lexclass START
  745.         ...
  746.         #lexclass A
  747.         ...
  748.         #lexclass B
  749.         ...
  750.         #lexclass START
  751.                                                                       (Item 58)
  752. ##.  A good example of the use of #lexclass are the definitions for C
  753. and C++ style comments, character literals, and string literals which
  754. can be found in pccts/lang/C/decl.g - or see Example 1 below.
  755.                                                                       (Item 59)
  756. ##.  The initial #lexclass of DLG is set by a data statement to START
  757. (which is 0).  Unlike ANTLRm, the traditional ANTLR macros (ANTLRf, ANTLRs,
  758. and ANTLR) do NOT reset the #lexclass. If you call ANTLR multiple times
  759. during a program (for instance to parse each statement of a line-oriented
  760. language independently) DLG will resume in the #lexclass that it was in
  761. when ANTLR returned.  If you want to restart DLG in the START state you
  762. should precede the call to ANTLR with
  763.  
  764.                 zzmode(START);
  765. or use:
  766.                 ANTLRm (myStartRule(),myStartMode);
  767.                                                                        Page 17
  768.  
  769.                                                                       (Item 60)
  770. ##.  Consider the problem of a grammar in which a statement is composed
  771. of clauses, each of which has its own #lexclass and in which a given
  772. word is "reserved" in some clauses and not others:
  773.  
  774.         #1;1-JAN-94 01:23:34;enable;a b c d;this is a comment;
  775.         #2;1-JAN-94 08:01:56;operator;smith;move to another station;
  776.         #3;1-JAN-94 09:10:11;move;old pos=5.0 new pos=6.0;operator request;
  777.         #4;1-JAN-94 10:11:12;set-alarm;beeper;2-JAN-94 00:00:01;
  778.  
  779. One would like to reuse a #lexclass if possible. There is no problem with
  780. maintaining a stack of modes (#lexclass numbers) and pushing a new mode
  781. onto the stack each time a new #lexclass subroutine is called.  How to do
  782. this is demonstrated in Example 5.  The problem appears when it is
  783. necessary to leave a #lexclass and return more than one level.  To be more
  784. specific, a #token action can only be executed when one or more characters
  785. is consumed - so to return through three levels of #lexclass calls would
  786. appear to require the consumption of at least three characters.  In the
  787. case of balanced constructs like "...", and '...', or (...) this is not a
  788. problem since the terminating character can be used to trigger the #token
  789. action. However, if the scan is terminated by a "separator", such as the
  790. semi-colon above (";"), one cannot use the same technique.  Once the
  791. semi-colon is consumed it is unavailable for the other #lexclass routines
  792. on the stack to see.
  793.  
  794. My solution is to allow the user to specify (during the call to pushMode)
  795. a "lookahead" routine to be called when the corresponding element of the
  796. mode stack is popped.  At that point the "lookahead" routine can examine
  797. zzchar to determine whether it also wants to pop the stack, and so on up
  798. the mode stack.  The consumption of a single character can result in
  799. popping multiple modes from the mode stack based on a single character of
  800. lookahead.  See the second part of Example 5 below.
  801.  
  802. Continuing with the example of the log file (above): each statement type
  803. has its fields in a specific order.  When the statement type is recognized
  804. a pointer is set to a list of the #lexclasses which is in the same order as
  805. the remaining fields of that kind of statement.  An action attached to
  806. every #token which recognizes a semi-colon (";") advances a pointer in
  807. the list of #lexclasses and then changes the #lexclass by calling zzmode()
  808. to set the #lexclass for the next field of the statement.
  809.  
  810.                                                                        Page 18
  811. ===============================================================================
  812. Section on rules
  813. -------------------------------------------------------------------------------
  814.                                                                       (Item 61)
  815. ##.  If you can't figure out what Antlr is doing try adding the -gd
  816. switch (debug via rule trace) and the -gs switch (perform lookahead
  817. tests using symbolic names for tokens rather than bit-oriented set
  818. tests).
  819.                                                                       (Item 62)
  820. ##.  Antlr can't handle left-handed recursion.  A rule such as:
  821.  
  822.         expr : expr Op expr
  823.              | Number
  824.              | String
  825.              ;
  826.  
  827. will have to be rewritten to something like this:
  828.  
  829.         expr : Number (Op expr)*
  830.              | String (Op expr)*
  831.              ;
  832.                                                                       (Item 63)
  833. ##.  Another sort of transformation required by Antlr is left-factoring:
  834.  
  835.         rule : STOP WHEN expr
  836.              | STOP ON expr
  837.              | STOP IN expr
  838.              :
  839.  
  840. These are easily distinguishable when k=2, but with a small amount of
  841. work they can be into a k=1 grammar:
  842.  
  843.         rule : STOP ( WHEN expr
  844.                     | ON expr
  845.                     | IN expr
  846.                     )
  847.              ;
  848.  
  849.     or
  850.         rule        : STOP rule_suffix
  851.                     ;
  852.         rule_suffix : WHEN expr
  853.                     | ON expr
  854.                     | IN expr
  855.                     ;
  856.  
  857. An extreme case of a grammar requiring a rewrite is in Example 12.
  858.                                                                       (Item 64)
  859. ##.  If a rule is not used (is an orphan) it can lead to unanticipated
  860. reports of ambiguity.  Use the ANTLR cross-reference option (-cr) to
  861. locate rules which are not referenced.  Not verified in version 1.20.
  862.                                                                       (Item 65)
  863. ##.  ANTLR attempts to deduce "start" rules by looking for rules which
  864. are not referenced by any other rules.  When it finds such a rule it
  865. assumes that an EOF token ("@") should be there and adds one if the
  866. user did not code one.  This is the only case, according to TJP, when
  867. ANTLR adds something to the user's grammar.
  868.                                                                        Page 19
  869.  
  870.                                                                       (Item 66)
  871. ##.  To express the idea "any single token is acceptable at this point"
  872. use the "." token wild-card.  This can be very useful for providing a
  873. context dependent error message, rather than the all purpose message
  874. "syntax error".
  875.  
  876.         if-stmt : IF "\(" expr "\)" stmt
  877.                 | IF .   <<printf("If statement requires expression ",
  878.                                         "enclosed in parenthesis");
  879.                            PARSE_FAIL;
  880.                          >>
  881.  
  882. It is probably best not to use expressions such as:
  883.  
  884.         ignore:  (.)*           /* Not a good idea */
  885.  
  886. which will gobble up everything to the end-of-file.
  887.                                                                       (Item 67)
  888. ##.  New to version 1.20 is the "~" operator for tokens.  It allows
  889. one to specify tokens which must NOT match in order to match a rule.
  890.  
  891. The "~" operator cannot be applied to rules.  To express the idea
  892. "if this rule doesn't match try to match this other rule" use
  893. syntactic predicates.
  894.                                                                       (Item 68)
  895. ##.  Some constructs which are bound to cause warnings about
  896. ambiguities:
  897.  
  898.         rule : a { ( b | c )* };
  899.  
  900.         rule : a { b };
  901.            b : ( c )*;
  902.  
  903.         rule : a c*;
  904.            a : b { c };
  905.  
  906.         rule : a { b | c | };
  907.                                                                        Page 20
  908.  
  909.                                                                       (Item 69)
  910. ##.  Don't confuse init-actions with actions which precede a rule
  911. (leading-actions). If the first element following the start of a rule
  912. or sub-rule is an action it is always interpreted as an init-action.
  913.  
  914. An init-action occurs in a scope which include the entire rule or sub-rule.
  915. An action which is NOT an init-action is enclosed in "{" and "}" during
  916. generation of code for the rule and has essentially zero scope - the
  917. action itself.
  918.  
  919. The difference between an init-action and an action which precedes a rule
  920. can be especially confusing when an action appears at the start of an
  921. alternative:
  922.  
  923. These APPEAR to be almost identical, but they aren't:
  924.  
  925.       b  : <<int i=0;>>  b1 > [i]  /* b1  <<...>> is an init-action        */
  926.          | <<int j=0;>>  b2 > [j]  /* b2  <<...>> is part of the rule      */
  927.          ;                         /*  and will cause a compilation error  */
  928.  
  929. On line "b1" the <<...>> appears immediately after the beginning of the
  930. rule making it an init-action.  On line "b2" the <<...>> does NOT appear at
  931. the start of a rule or sub-rule, thus it is interpreted as an action which
  932. happens to precede the rule.
  933.  
  934. This can be especially dangerous if you are in the habit of rearranging
  935. the order of alternatives in a rule.  For instance:
  936.  
  937. Changing this:
  938.  
  939.       b  : <<int i=0,j=0;>> <<i++;>>  b1 > [i]       /* c1 */
  940.          | <<j++;>>  b1 > [i]                        /* c2 */
  941.          ;
  942.  
  943. to:
  944.  
  945.       b  : /* empty production */                    /* d1 */
  946.          | <<int i=0,j=0;>> <<i++;>>  b1 > [i]       /* d2 */
  947.          | <<j++;>>  b1 > [i]
  948.          ;
  949.  
  950. or to this:
  951.  
  952.       b
  953.          : <<j++;>>  b1 > [i]                        /* e1 */
  954.          | <<int i=0,j=0;>> <<i++;>>  b1 > [i]       /* e2 */
  955.  
  956. changes an init-action into a non-init action, and vice-versa.
  957.                                                                        Page 21
  958.  
  959.                                                                       (Item 70)
  960. ##.  A particularly nasty form of the init-action problem is when
  961. an empty sub-rule has an associated action:
  962.  
  963.         rule!: ID (
  964.                     /* empty */
  965.                         <<#0=#[ID,$1.1];>>
  966.                   | array_bounds
  967.                         <<#0=#[T_array_declaration,$1.1],#1);>>
  968.                   )
  969.              ;
  970.  
  971. Since there is no reserved word in pccts for epsilon, the action
  972. for the empty arm of the sub-rule becomes the init-action.  For
  973. this reason it's wise to follow one of the following conventions
  974. (1) represent epsilon with an empty rule "()" or (2) put empty
  975. as the last rule in a list of alternatives:
  976.  
  977.         rule!: ID (
  978.                     ()  <<#0=#[ID,$1.1];>>
  979.                   | array_bounds
  980.                         <<#0=#[T_array_declaration,$1.1],#1);>>
  981.                   )
  982.              ;
  983.  
  984. The cost of using "()" to represent epsilon is the execution of the macro
  985. zzBLOCK() at the start of the sub-rule and zzEXIT() at the end of the
  986. sub-rule. Macro zzBLOCK() creates a temporary stack pointer for the
  987. attribute stack and checks for overflow.  Macro zzEXIT() pops any
  988. attributes that might have been placed on attribute stack.  Since no
  989. attribute stack operations take place for epsilon this is wasted CPU
  990. cycles, however this is probably not a significant cost for many users.
  991.                                                                       (Item 71)
  992. ##.  Another form of problem caused by init-action occurs when one
  993. comments out a rule in the grammar in order to test an idea:
  994.  
  995.         rule                          /* a1 */
  996.                 : <<init-action;>     /* a2 */
  997.         ////      rule_a              /* a3 */
  998.                 | rule_b              /* a4 */
  999.                 | rule_c              /* a5 */
  1000.  
  1001. In this case one only wanted to comment out the "rule_a" reference
  1002. in line "a3".  The reference is indeed gone, but the change has
  1003. introduced an epsilon production - which probably creates a large
  1004. number of ambiguities.  Without the init-action the ":" would have
  1005. probably have been commented out also, and ANTLR would report a
  1006. syntax error - thus preventing one from shooting oneself in the foot.
  1007.                                                                       (Item 72)
  1008. ##.   In the case of sub-rules such as (...)+, (...)*, and {...} the
  1009. init-action is executed just once before the sub-rule is entered.
  1010. Consider the following example from section 3.6.1 (page 29) of the 1.00
  1011. manual:
  1012.  
  1013.         a : <<List *p=NULL;>>                   // initialize list
  1014.             Type
  1015.             (  <<int i=0;>>                     // initialize index
  1016.                Var <<append(p,i++,$1);>>
  1017.             )*
  1018.             <<OperateOn(p);>>
  1019.           ;
  1020.                                                                        Page 22
  1021.  
  1022.                                                                       (Item 73)
  1023. ##.  Associativity and precedence of operations is determined by
  1024. nesting of rules.  In the example below "=" associates to the right
  1025. and has the lowest precedence.  Operators "+" and "*" associate to
  1026. the left with "*" having the highest precedence.
  1027.  
  1028.         expr0   : expr1 {"=" expr0};
  1029.         expr1   : expr2 ("\+" expr2)*;
  1030.         expr2   : expr3 ("\*" expr3)*;
  1031.         expr3   : ID;
  1032.  
  1033. See Example 2.
  1034.                                                                       (Item 74)
  1035. ##.  Fail actions for a rule can be placed after the final ";" of
  1036. a rule.  These will be:
  1037.  
  1038.          "executed after a syntax error is detected but before
  1039.           a message is printed and the attributes have been destroyed.
  1040.           However, attributes are not valid here because one does not
  1041.           know at what point the error occurred and which attributes
  1042.           even exist.  Fail actions are often useful for cleaning up
  1043.           data structures or freeing memory."
  1044.  
  1045.                                                 (Page 29 of 1.00 manual)
  1046.  
  1047.       Example of a fail action:
  1048.  
  1049.           a : <<List *p=NULL;>>
  1050.               ( Var <<append(p,$1);>> )+
  1051.                   <<operateOn(p);rmlist(p);>>
  1052.             ; <<rmlist(p);>>
  1053.               **************  <--- Fail Action
  1054.                                                                       (Item 75)
  1055. ##.  When you have rules with large amounts of lookahead (that may
  1056. cross several lines) you can use the ANTLR -gk option to make an
  1057. ANTLR-generated parser delay lookahead fetches until absolutely
  1058. necessary. To get better line number information (e.g. for error
  1059. messages or #line directives) place an action which will save
  1060. "zzline" in a variable at the start of the production where you
  1061. want better line number information:
  1062.  
  1063.     a : <<int saveCurrentLine;>>
  1064.         <<saveCurrentLine = zzline;>>   A B C
  1065.                  << /* use saveCurrentLine not zzline here */ >>
  1066.       | <<saveCurrentLine = zzline;>>   A B D
  1067.                  << /* use saveCurrentLine not zzline here */ >>
  1068.       ;
  1069.  
  1070. After the production has been matched you can use saveCurrentLine
  1071. rather than the bogus "zzline".
  1072.  
  1073. Contributed by Terence "The ANTLR Guy" Parr (parrt@acm.org)
  1074.  
  1075. In version 1.20 a new macro, ZZINF_LINE(), was added to extract line
  1076. information in a manner similar to LATEXT when using infinite lookahead
  1077. mode.  See the page 6 of the 1.20 release notes for more information.
  1078. There is nothing like ZZINF_COL() for column information, but it should
  1079. be easy to create using ZZINF_LINE() as a model. Maybe.
  1080.                                                                       (Item 76)
  1081. ##.  An easy way to get a list of the names of all the rules is
  1082. to grep tokens.h for the string "void" or edit the output from ANTLR
  1083. run with the  -cr option (cross-reference).
  1084.                                                                        Page 23
  1085.  
  1086.                                                                       (Item 77)
  1087. ##.  It took me a while to understand in an intuitive way the difference
  1088. between full LL(k) lookahead given by the ANTLR -k switch and the
  1089. linear approximation given by the ANTLR -ck switch.  This was in spite
  1090. of the example given in section 5 (pages 18 to 21) of the 1.10 release notes.
  1091.  
  1092. Most of the time I run ANTLR with -k 1 and -ck 2.  Because I didn't
  1093. understand the linear approximation I didn't understand the warnings about
  1094. ambiguity.  I couldn't understand why ANLTR would complain about something
  1095. which I thought was obviously parse-able with the lookahead available.
  1096. Was it a bug or was it me ? I would try to make the messages go away
  1097. totally, which was sometimes very hard.  If I had understood the linear
  1098. approximation I might have been able to fix them easily or at least have
  1099. realized that there was no problem with the grammar, just with the
  1100. limitations of the linear approximation.
  1101.  
  1102. I will restrict the discussion to the case of "-k 1" and "-ck 2".
  1103.  
  1104. Consider the following example:
  1105.  
  1106.         rule1   : rule2a | rule2b | rule2c ;
  1107.         rule2a  : A X | B Y | C Z ;
  1108.         rule2b  : B X | B Z ;
  1109.         rule2c  : C X ;
  1110.  
  1111. It should be clear that with the sentence being only two tokens this
  1112. should be parseable with LL(2).
  1113.  
  1114. Instead, because k=1 and ck=2 ANTLR will produce the following messages:
  1115.  
  1116.         /pccts120/bin/antlr -k 1 -gs -ck 2 -gh example.g
  1117.         Antlr parser generator   Version 1.20   1989-1994
  1118.         example.g, line 23: warning: alts 1 and 2 of the rule itself
  1119.                  ambiguous upon { B }, { X Z }
  1120.         example.g, line 23: warning: alts 1 and 3 of the rule itself
  1121.                  ambiguous upon { C }, { X }
  1122.  
  1123. The code generated resembles the following:
  1124.  
  1125.         if      (LA(1)==A || LA(1)==B || LA(1)==C) &&
  1126.                 (LA(2)==X || LA(2)==Y || LA(2)==Z) then rule2a()
  1127.  
  1128.         else if (LA(1)==B) &&
  1129.                 (LA(2)==X || LA(2)==Y) then rule2b()
  1130.  
  1131.         else if (LA(1)==C) &&
  1132.                 (LA(2)==Z) then rule3a()
  1133.         ...
  1134.  
  1135. This might be called "product-of-sums".  There is an "or" part for
  1136. LA(1), an "or" part for LA(2), and they are combined using "and".
  1137. To match, the first lookahead token must be in the first set and the second
  1138. lookahead token must be in the second set.  It doesn't matter that what
  1139. one really wants is:
  1140.  
  1141.                                                                        Page 24
  1142.         if      (LA(1)==A && LA(2)==X) ||
  1143.                 (LA(1)==B && LA(2)==Y) ||
  1144.                 (LA(1)==C && LA(2)==Z) then rule2a()
  1145.  
  1146.         else if (LA(1)==B && LA(2)==X) ||
  1147.                 (LA(1)==B && LA(2)==Z) then rule2b()
  1148.  
  1149.         else if (LA(1)==C && LA(2)==X) then rule2c()
  1150.  
  1151. This happens to be "product-of-sums" but the real problem is that each
  1152. product involves one element from LA(1) and one from LA(2) and as the
  1153. number of possible tokens increases the number of terms grows as N**2.
  1154. With the linear approximation the number of terms grows (surprise)
  1155. linearly in the number of tokens.
  1156.  
  1157. ANTLR won't do this with k=1, it will only do "product-of-sums". However,
  1158. all is not lost - you simply add a few well chosen semantic predicates
  1159. which you have computed using your LL(k>1), all purpose, carbon based,
  1160. analog computer.
  1161.  
  1162. The linear approximation selects for each branch of the "if" a set which
  1163. MAY include more than what is wanted. It never selects a subset of the
  1164. correct lookahead sets!  We simply insert a hand-coded version of the
  1165. LL(2) computation.  It's ugly, especially in this case, but it fixes the
  1166. problem.  In large grammars it may not be possible to run ANTLR with k=2,
  1167. so this fixes a few rules which cause problems.  The generated parser may
  1168. run faster because it will have to evaluate fewer terms at execution time.
  1169.  
  1170.         <<
  1171.         int bypass_rule2a() {
  1172.           if ( LA(1)==B && LA(2)==Y ) return 0;
  1173.           if ( LA(1)==B ) return 1;
  1174.           if ( LA(1)==C && LA(2)==X ) return 1;
  1175.           return 0;
  1176.         }
  1177.         >>
  1178.  
  1179.         rule1   :
  1180.                 <<bypass_rule2a()>>? rule2a | rule2b | rule2c ;
  1181.         rule2a  : A X | B Y | C Z ;
  1182.         rule2b  : B X | B Z ;
  1183.         rule2c  : C X ;
  1184.  
  1185. The real cases I've coded  have shorter code sequences in the semantic
  1186. predicate.  I coded this as a function to make it easier to read and
  1187. because there is a bug in 1.1x and 1.2x which prevents semantic predicates
  1188. from crossing lines.  Another reason to use a function (or macro) is to
  1189. make it easier to read the generated code to determine when your semantic
  1190. predicate is being hoisted too high (it's easy to find references to a
  1191. function name with the editor - but difficult to locate a particular
  1192. sequence of "LA(1)" and "LA(2)" tests.  Predicate hoisting is a separate
  1193. issue which is described elsewhere in this note.
  1194.  
  1195.                                                                        Page 25
  1196. In some cases of reported ambiguity it is not necessary to add semantic
  1197. predicates because no VALID token sequence could get to the wrong rule.
  1198. If the token sequence were invalid it would be detected by the grammar
  1199. eventually, although perhaps not where one might wish.  In other cases
  1200. the only necessary action is a reordering of the ambiguous rules so
  1201. that a more specific rule is tested first.  The error messages still
  1202. appear, but one can ignore them or place a trivial semantic predicate
  1203. (i.e. <<1>>? ) in front of the later rules.  This makes ANTLR happy
  1204. because it thinks you've added a semantic predicate which fixes things.
  1205.  
  1206. Some constructs just invite problems.  For instance in C++ with a suitable
  1207. definition of the class "C" one can write:
  1208.  
  1209.                 C a,b,c                         /* a1 */
  1210.                 a.func1(b);                     /* a2 */
  1211.                 a.func2()=c;                    /* a3 */
  1212.                 a = b;                          /* a4 */
  1213.                 a.operator =(b);                /* a5 */
  1214.  
  1215. Statement a5 happens to place an "=" (or any of the usual C++ operators)
  1216. in a token position where it can cause a lot of ambiguity in the lookahead.
  1217. set.  I eventually solved this particular problem by creating a special
  1218. #lexclass for things which follow "operator".  I use an entirely different
  1219. token number for such operators - thereby avoiding the whole problem.
  1220.  
  1221.         //
  1222.         //  C++ operator sequences
  1223.         //
  1224.         //  operator <type_name>
  1225.         //  operator <special characters>
  1226.         //
  1227.         //  There must be at least one non-alphanumeric character between
  1228.         //  "operator" and operator name - otherwise they would be run
  1229.         //  together - ("operatorint" instead of "operator int")
  1230.         //
  1231.  
  1232.         #lexclass LEX_OPERATOR
  1233.         #token  FILLER_C1               "[\ \t]*"
  1234.                   <<zzskip();
  1235.                    if( isalnum(zzchar) ) zzmode(START);
  1236.                   >>
  1237.         #token  OPERATOR_STRING         "[\+\-\*\/\%\^\&\|\~\!\=\<\>]*"
  1238.                                 <<zzmode(START);>>
  1239.         #token  FILLER_C2               "\(\) | \[\] "
  1240.                                 <<NLA=OPERATOR_STRING;zzmode(START);>>
  1241.  
  1242.  
  1243.                                                                        Page 26
  1244. ===============================================================================
  1245. Section on Attributes
  1246. -------------------------------------------------------------------------------
  1247.                                                                       (Item 78)
  1248. ##.  With version 1.30 one will no longer have to refer to attributes or
  1249. ASTs of a rule using numbers.
  1250.  
  1251.     prior to version 1.30:
  1252.         rule : X Y Z        <<printf("%s %s %s\n",$1,$2,$3);>>
  1253.  
  1254.     with version 1.30:
  1255.         rule : x:X y:Y z:Z  <<printf("%s %s %s\n",$x,$y,$z);>>
  1256.  
  1257. Many of the examples in this section need to be revised to reflect the
  1258. use of symbolic tags.
  1259.                                                                       (Item 79)
  1260. ##.  Attributes are built automatically only for terminals.  For
  1261. rules (non-terminals) one must assign an attribute to $0, use the
  1262. $[token,...] convention for creating attributes, or use zzcr_attr().
  1263.                                                                       (Item 80)
  1264. ##.  The way to access the text (or whatever) part of an attribute
  1265. depends on the way the attribute is stored.
  1266.  
  1267. If one uses the pccts supplied routine "pccts/h/charbuf.h" then
  1268.  
  1269.         id : "[a-z]+"           <<printf("Token is %s\n",$1.text);>>
  1270.  
  1271. If one uses the pccts supplied routine "pccts/h/charptr.c" and
  1272. "pccts/h/charptr.h" then:
  1273.  
  1274.         id : "[a-z]+"           <<printf("Token is %s\n",$1);>>
  1275.  
  1276. If one uses the pccts supplied routine "pccts/h/int.h" (which
  1277. stores numbers only) then:
  1278.  
  1279.         number : "[0-9]+"       <<printf ("Token is %d\n",$1);>>
  1280.  
  1281.                 Note the use of %d rather than %s in the printf() format.
  1282.                                                                       (Item 81)
  1283. ##.  The expression $$ refers to the attribute of the named rule.
  1284. The expression $0 refers to the attribute of the the enclosing rule,
  1285. (which might be a sub-rule).
  1286.  
  1287.         rule : a b (c d (e f g) h) i
  1288.  
  1289. For (e f g) $0 becomes $3 of (c d  ... h).  For (c d ... h) $0 becomes
  1290. $3 of (a b ... i).  However $$ always is equivalent to $rule.
  1291.                                                                       (Item 82)
  1292. ##.  If you define a zzcr_attr() or zzmk_attr() which allocates resources
  1293. such as strings from the heap don't forget to define a zzd_attr() routine
  1294. to release the resources when the attribute is deleted.
  1295.                                                                       (Item 83)
  1296. ##.  Attributes go out of scope when the rule or sub-rule that defines
  1297. them is exited.  Don't try to pass them to an outer rule or a sibling
  1298. rule.  The only exception is  $0 which may be passed back to the containing
  1299. rule as a return argument.  However, if the attribute contains a pointer
  1300. which is copied (e.g. pccts/h/charptr.c) then extra caution is required
  1301. because of the actions of zzd_attr().  For C++ users this should be
  1302. implemented in the class copy constructor. The version of pccts/h/charptr.*
  1303. distributed with pccts does not use C++ features.  See the next item for
  1304. more information.
  1305.                                                                        Page 27
  1306.  
  1307.                                                                       (Item 84)
  1308. ##.  The pccts/h/charptr.c routines use a pointer to a string.  The string
  1309. itself will go out of scope when the rule or sub-rule is exited.  Why ?
  1310. The string is copied to the heap when ANTLR calls the routine zzcr_attr()
  1311. supplied by charptr.c - however ANTLR also calls the charptr.c supplied
  1312. routine zzd_attr() (which frees the allocated string) as soon as the rule or
  1313. sub-rule exits.  The result is that in order to pass charptr.c strings to
  1314. outer rules (for instance to $0) it is necessary to make an independent
  1315. copy of the string using strdup or else zero the pointer to prevent its
  1316. deallocation.
  1317.                                                                       (Item 85)
  1318. ##.  To initialize $0 of a sub-rule use a construct like the following:
  1319.  
  1320.    *** Note: This feature has been removed from version 1.30 of pccts. ***
  1321.  
  1322.         decl : typeID
  1323.                Var      <<$2.type = $1;>>
  1324.                ( "," Var  <<$2.type = $0;>>)*[$1]
  1325.                                              ****       <--------------
  1326.  
  1327.                      See section 4.1.6.1 (page 29) of the 1.00 manual
  1328.                                                                       (Item 86)
  1329. ##.  One can use the zzdef0() macro to define a standard method for
  1330. initializing $0 of a rule or sub-rule.  If the macro is defined it is
  1331. invoked as zzdef0(&($0)).
  1332.  
  1333.      See section 4.1.6.1 (page 29) of the 1.00 manual
  1334.  
  1335. I believe that for C++ users this would be handled by the class constructor.
  1336.                                                                       (Item 87)
  1337. ##.  If you construct temporary attributes in the middle of the
  1338. recognition of a rule, remember to deallocate the structure should the
  1339. rule fail.  The code for failure goes after the ";" and before the next
  1340. rule.  For this reason it is sometimes desirable to defer some processing
  1341. until the rule is recognized rather than the most convenient place.
  1342.  
  1343.         #include "pccts/h/charptr.h"
  1344.  
  1345.         ;statement!
  1346.                 : <<char *label=0;>>
  1347.                   {ID COLON  <<label=MYstrdup($1);>> }
  1348.                          statement_without_label
  1349.                                 <<#0=#(#[T_statement,label],#2);
  1350.                                   if (label!=0) free(label);
  1351.                                         // AST #1 is undefined
  1352.                                         // AST #2 is returned by
  1353.                                         //   statement_without_label
  1354.                                 >>
  1355.         ;<<if (label !=0) free(label);>>
  1356.  
  1357. In the above example attributes are handled by charptr.*.  Readers of this
  1358. note have been warned earlier about its dangers.  The routine I have
  1359. written to construct ASTs from attributes (invoked by #[int,char *]) knows
  1360. about this behavior and automatically makes a copy of the character string
  1361. when it constructs the AST.  This makes the copy created by the explicit
  1362. call to MYstrdup redundant once the AST has been constructed.  If the call
  1363. to "statement_without_label" fails then the temporary copy must be
  1364. deallocated.
  1365.  
  1366.                                                                        Page 28
  1367. ===============================================================================
  1368. Section on ASTs
  1369. -------------------------------------------------------------------------------
  1370.                                                                       (Item 88)
  1371. ##.  With version 1.30 one will no longer have to refer to attributes or
  1372. ASTs of a rule using numbers:
  1373.  
  1374.         prior to version 1.30:
  1375.                 rule ! : x y z            <<#0=#(#1 #2 #3);>>
  1376.  
  1377.         with version 1.30:
  1378.                 rule ! : xx:x yy:y zz:z   <<#0=#(#xx,#yy,#zz);>>
  1379.  
  1380. Many of the examples in this section need to be revised to reflect the
  1381. use of symbolic tags.
  1382.                                                                       (Item 89)
  1383. ##.  If you define a zzcr_ast() or zzmk_ast() which allocates resources
  1384. such as strings from the heap don't forget to define a zzd_ast() routine
  1385. to release the resources when the AST is deleted.  For C++ users this
  1386. should be implemented as part of the class destructor.
  1387.                                                                       (Item 90)
  1388. ##.  Don't confuse #[...] with #(...).
  1389.  
  1390. The first creates a single AST node (usually from a token identifier and
  1391. an attribute) using the routine zzmk_ast().  The zzmk_ast() routine must be
  1392. supplied by the user (or selected from one of the pccts supplied ones such
  1393. as pccts/h/charbuf.h, pccts/h/charptr.*, and pccts/h/int.h).
  1394.  
  1395. The second creates an AST list (usually more than a single node) from other
  1396. ASTs by filling in the "down" field of the first node in the list to create
  1397. a root node, and the "sibling" fields of each of remaining ASTs in the
  1398. list.  A null pointer is put in the sibling field of the last AST in the
  1399. list.  This is performed by the pccts supplied routine zztmake().
  1400.  
  1401.      #token ID                  "[a-z]*"
  1402.      #token COLON               ":"
  1403.      #token STMT_WITH_LABEL
  1404.  
  1405.      id!   : ID <<#0=#[STMT_WITH_LABEL,$1];>>                   /* a1 */
  1406.  
  1407.                 Creates an AST.  The AST (a single node)
  1408.                 contains STMT_WITH_LABEL in the token
  1409.                 field - given a traditional version of
  1410.                 zzmk_ast().
  1411.  
  1412.      rule! : id COLON expr                                      /* a2 */
  1413.                 <<#0=#(#1,#3);>>
  1414.  
  1415.                 Creates an AST list with the ID at its
  1416.                 root and "expr" as its first (and only) child.
  1417.  
  1418. The following example (a3) is equivalent to a1, but more confusing because
  1419. the two steps above have been combined into a single action statement:
  1420.  
  1421.      rule! : ID COLON expr
  1422.                 <<#0=#(#[STMT_WITH_LABEL,$1],#3);>>             /* a3 */
  1423.                                                                        Page 29
  1424.  
  1425.                                                                       (Item 91)
  1426. ##.  If you construct temporary ASTs in the middle of the recognition of a
  1427. rule, remember to deallocate the structure should the rule fail.  The code
  1428. for failure goes after the ";" and before the next rule.  For this reason
  1429. it is sometimes desirable to defer some processing until the rule is
  1430. recognized rather than the most appropriate place.  For C++ users this
  1431. might be implemented as part of the class destructor.
  1432.  
  1433. If the temporary is an AST returned by a called rule then you'll probably
  1434. have to call zzfree_ast() to release the entire AST tree.  Consider
  1435. the following example:
  1436.  
  1437.    obj_name!                                                   /* a1  */
  1438.         : <<AST *node=0;>>                                     /* a2  */
  1439.           class_name <<node=#1;>>                              /* a3  */
  1440.                      (                                         /* a4  */
  1441.                        () /* empty */                          /* a5  */
  1442.                                 <<#0=node;node=0;>>            /* a6  */
  1443.                        | COLON_COLON follows_dot_class[node]   /* a7  */
  1444.                                 <<#0=#2;node=0;>>              /* a8  */
  1445.                      )                                         /* a9  */
  1446.           .........                                            /* a10 */
  1447.                                                                /* a11 */
  1448.          ; <<if (node!=0) zzfree_ast(node);>>                  /* a12 */
  1449.  
  1450. In this case "class_name" may return a full AST tree (not a trivial tree)
  1451. because of information required to represent template classes (e.g.
  1452. dictionary<int,1000> is a "class_name").  This tree ("node") is passed to
  1453. another rule ("follows_dot_class") which uses it to construct another AST
  1454. tree which incorporates it.  If "follows_dot_class" succeeds then node is
  1455. set to 0 (lines a6 or a8) because the tree is now referenced via #2.  If
  1456. "follows_dot_class" fails then the entire tree created by class_name must
  1457. be deallocated (line a12).  The temporary "node" must be used because there
  1458. is no convenient way (such as #1.1) to refer to class_name from within the
  1459. sub-rule.
  1460.  
  1461. Please note the use of an empty sub-rule ("()" on line a5) to avoid the nasty
  1462. init-action problem mentioned earlier.
  1463.                                                                       (Item 92)
  1464. ##.  Example 6 shows debugging code to help locate ASTs that were created
  1465. but never deleted.
  1466.                                                                       (Item 93)
  1467. ##.  If you want to place prototypes for routines that have an AST
  1468. as an argument in the #header directive you should explicitly
  1469. #include "ast.h" after the #define AST_FIELDS and before any references
  1470. to AST:
  1471.  
  1472.         #define AST_FIELDS int token;char *text;
  1473.         #include "ast.h"
  1474.         #define zzcr_ast(ast,attr,tok,astText) \
  1475.                 create_ast(ast,attr,tok,text)
  1476.         void create_ast (AST *ast,Attr *attr,int tok,char *text);
  1477.                                                                        Page 30
  1478.  
  1479.                                                                       (Item 94)
  1480. ##.  The make-a-root operator for ASTs ("^") can be applied only to
  1481. terminals.  (This includes items identified in #token ,#tokclass, and
  1482. #tokdef statements). I think this is because a child rule might return a
  1483. tree rather than a single AST.  If it did then it could not be made into a
  1484. root as it is already a root and the corresponding fields of the structure
  1485. are already in use.  To make an AST returned by a called rule a root use
  1486. the expression: #(root-rule sibling1 sibling2 sibling3).
  1487.  
  1488.         add !         :  expr ("\+"^ expr) ;    // Is ok
  1489.  
  1490.         addOperator ! :  expr (AddOp expr)      // Is NOT ok
  1491.         addOp         : "\+" | "-";             //
  1492.  
  1493. Example 2 describes a workaround for this restriction.
  1494.                                                                       (Item 95)
  1495. ##.  Because it is not possible to use an already constructed AST tree
  1496. as the root of a new tree (unless it's a trivial tree with no children)
  1497. one should be suspicious of any constructs like the following:
  1498.  
  1499.         rule! : ........ <<#0=#(#1,...)...;>>
  1500.                                 ** <=====================
  1501.  
  1502. If #1 is a non-trivial tree its existing children will be lost when the
  1503. new tree is constructed for assignment to #0.
  1504.                                                                       (Item 96)
  1505. ##.  Do not assign to #0 of a rule unless automatic construction of ASTs
  1506. has been disabled using the "!" operator:
  1507.  
  1508.                 a! : x y z <<#0=#(#1,#2,#3);>>  // ok
  1509.                 a  : x y z <<#0=#(#1,#2,#3);>>  // NOT ok
  1510.  
  1511. The reason for the restriction is that assignment to #0 will cause any
  1512. ASTs pointed to by #0 to be lost when the pointer is overwritten.
  1513.  
  1514. The stated restriction is somewhat stronger than necessary.  You can
  1515. assign to #0 even when using automated AST construction, if the old
  1516. tree pointed to by #0 is part of the new tree constructed by #(...).
  1517. For example:
  1518.  
  1519.         #token COMMA    ","
  1520.         #token STMT_LIST
  1521.  
  1522.         stmt_list: stmt (COMMA stmt)*  <<#0=#(#[STMT_LIST],#0);>>
  1523.  
  1524. The automatically constructed tree pointed to by #0 is just put at the
  1525. end of the new list, so nothing is lost.
  1526.  
  1527. If you reassign to #0 in the middle of the rule, automatic tree
  1528. construction will result in the addition of remaining elements at the end
  1529. of the new tree.  This is not recommended by TJP.
  1530.  
  1531. Special care must be used when combining the make-a-root operator
  1532. (e.g. rule: expr OP^ expr) with this transgression (assignment to #0 when
  1533. automatic tree construction is selected).
  1534.                                                                        Page 31
  1535.  
  1536.                                                                       (Item 97)
  1537. ##.  Even when automatic construction of ASTs is turned off in a rule the
  1538. called rules still return the ASTs that they constructed.  The same applies
  1539. when the "!" operator is applied to a called rule.  This is hard to
  1540. believe when one sees a rule like the following:
  1541.  
  1542.         rule: a! b! c!
  1543.  
  1544. generate (in part) a sequence of operations like:
  1545.  
  1546.         _ast = NULL; a(&_ast);
  1547.         _ast = NULL; b(&_ast);
  1548.         _ast = NULL; c(&_ast);
  1549.  
  1550. It appears that the AST pointer is being assigned to a temporary where it
  1551. becomes inaccessible.  This is not the case at all. The called rule is
  1552. responsible for placing a pointer to the AST which is constructed onto a
  1553. stack of AST pointers.  The stack of AST pointers is normally in global
  1554. scope with ZZAST_STACKSIZE elements.
  1555.  
  1556. (The "!" operator simply inhibits the automatic construction of the
  1557. AST trees.  It does not prevent the construction of the ASTs themselves.
  1558. When calling a rule which constructs ASTs and not using the result one
  1559. must destroy the constructed AST using zzfree_ast() in order to avoid a
  1560. memory leak.  See Example 6 below for code which aids in tracking lost
  1561. ASTs).
  1562.  
  1563. Consider the following examples (using the list notation of page 45 of
  1564. the 1.00 manual):
  1565.  
  1566.   a: A;
  1567.   b: B;
  1568.   c: C;
  1569.  
  1570.   #token T_abc_node
  1571.  
  1572.   rule   : a b c ;   <<;>>                   /* AST list (0 A B C) without root */
  1573.   rule ! : a b c     <<#0=#(0,#1,#2,#3);>>   /* AST list (0 A B C) without root */
  1574.   rule   : a! b! c!  <<#0=#(0,#1,#2,#3);>>   /* AST list (0 A B C) without root */
  1575.   rule   : a^ b c                            /* AST tree (A B C) with root A    */
  1576.   rule ! : a b c     <<#0=#(#1,#2,#3);>>     /* AST tree (A B C) with root A    */
  1577.  
  1578.   rule ! : a b c     <<#0=#(#[T_abc_node,0],#1,#2,#3);>>
  1579.                                              /* AST tree (T_abc_node A B C)     */
  1580.                                              /*   with root T_abc_node          */
  1581.   rule   : a b c     <<#0=#(#[T_abc_node,0],#0);>>          /* the same as above */
  1582.   rule   : a! b! c!  <<#0=#(#[T_abc_node,0],#1,#2,#3);>>    /* the same as above */
  1583.  
  1584.   rule ! : a b c     <<#0=#(toAST(T_abc_node),#1,#2,#3);>>  /* the same as above */
  1585.   rule   : a b c     <<#0=#(toAST(T_abc_node),#0);>>        /* the same as above */
  1586.   rule   : a! b! c!  <<#0=#(toAST(T_abc_node),#1,#2,#3);>>  /* the same as above */
  1587.  
  1588. The routine "toAST()" calls zzmk_ast() to construct an AST given the token
  1589. number. For a typical version of zzmk_ast() it would look something like the
  1590. following:
  1591.  
  1592.         AST * toAST (int tokenID) {
  1593.            return zzmk_ast (zzastnew(),tokenID,NULL);
  1594.         }
  1595.  
  1596.                                                                        Page 32
  1597. I find toAST() more convenient than passing the extra arguments to zzmk_ast()
  1598. using a construct like #[T_abc_node,0] or writing zzmk_ast() with varargs.
  1599. Using varargs defeats most forms of inter-procedural type checking (unless you
  1600. are using C++ which allows overloaded function names).
  1601.                                                                       (Item 98)
  1602. ##.  There is an idiom which can be useful when combining automatic AST
  1603. construction with optional clauses in a grammar.  Suppose one wants to
  1604. make the following transformation:
  1605.  
  1606.         rule :  lhs        => #(toAST(T_simple),#1)
  1607.         rule :  lhs  rhs   => #(toAST(T_complex),#1,#2)
  1608.  
  1609. Both lhs and rhs considered separately may be suitable for automatic
  1610. construction of ASTs, but the change in the label from "simple" to "complex"
  1611. appears to require manual tree construction.  Use the following idiom:
  1612.  
  1613.         rule : lhs (
  1614.                         ()      <<#0=#(toAST(T_simple),#0);>>
  1615.                         | rhs   <<#0=#(toAST(T_complex),#0,#1);>>
  1616.                    )
  1617.                                                                       (Item 99)
  1618. ##.  If you use ASTs you have to pass a root AST to ANTLR.
  1619.  
  1620.                 AST     *root=NULL;
  1621.         again:
  1622.                 ANTLR (start(&root),stdin);
  1623.                 walk_the_tree(root);
  1624.                 zzfree_ast(root);
  1625.                 root=NULL;
  1626.                 goto again;
  1627.                                                                       (Item 100)
  1628. ##.  zzfree_ast(AST *tree) will recursively descend the AST tree and free
  1629. all sub-trees.  The user should supply a routine zzd_ast()  to free any
  1630. resources used by a single node - such as pointers to character strings
  1631. allocated on the heap.  See Example 2 on associativity and precedence.
  1632.                                                                       (Item 101)
  1633. ##.  AST elements in rules are assigned numbers in the same fashion as
  1634. attributes with three exceptions:
  1635.  
  1636.      1. A hole is left in the sequence when sub-rules are encountered.
  1637.         (e.g. "(...)+", "(...)*", and "{...}").
  1638.      2. #0 is the AST of the named rule, not the sub-rule - see the next item
  1639.      3. There is nothing analogous to $i.j notation (which allows one
  1640.         to refer to attributes from earlier in the rule).  In other words,
  1641.         you can't use #i.j notation to refer to an AST created earlier
  1642.         in the rule.
  1643.  
  1644.                 ========================================================
  1645.                 Version 1.30 of Antlr allows one to use symbolic tags
  1646.                 rather than numbers to refer to matched elements of a rule.
  1647.                 They are similar in appearance to Sorcerer.
  1648.                 See the version 1.3 release notes for more information
  1649.                 ========================================================
  1650.  
  1651. Consider the following example:
  1652.  
  1653.      a : b              // B is #1 for the rule
  1654.          (c d)*         // C is #1 when scope is inside the sub-rule
  1655.                         // D is #2 when scope is inside the sub-rule
  1656.                         //   You may *NOT* refer to b as #1.1
  1657.          e              // E is #3 for the rule
  1658.                         // There is NO #2 for the rule
  1659.                                                                        Page 33
  1660.  
  1661.                                                                       (Item 102)
  1662. ##.  The expression #0 refers to the AST of the named rule.  Thus it is
  1663. a misnomer and (for consistentcy) should probably have been named ## or #$.
  1664. There is nothing equivalent to $0 for ASTs.  This is probably because
  1665. sub-rules aren't assigned AST numbers in a rule.
  1666.                                                                       (Item 103)
  1667. ##.  Associativity and precedence of operations is determined by nesting
  1668. of rules.  In the example below "=" associates to the right and has the
  1669. lowest precedence.  Operators "+" and "*" associate to the left with "*"
  1670. having the highest precedence.
  1671.  
  1672.         expr0   : expr1 {"=" expr0};
  1673.         expr1   : expr2 ("\+" expr2)*;
  1674.         expr2   : expr3 ("\*" expr3)*;
  1675.         expr3   : ID;
  1676.  
  1677. In Example 2 the zzpre_ast() routine is used to walk all the AST nodes.
  1678. The AST nodes are numbered during creation so that one can see the order in
  1679. which they are created and the order in which they are deleted.  Do not
  1680. confuse the "#" in the sample output with the AST numbers used to refer to
  1681. elements of a rule in the action part of a the rule.  The "#" in the
  1682. sample output are just to make it simpler to match elements of the
  1683. expression tree with the order in which zzd_ast() is called for each node in
  1684. the tree.
  1685.                                                                       (Item 104)
  1686. ##.  If the make-a-root operator were NOT used in the rules:
  1687.  
  1688.         ;expr0  : expr1 {"=" expr0}
  1689.         ;expr1  : expr2 ("\+" expr2)*
  1690.         ;expr2  : expr3 ("\*" expr3)*
  1691.         ;expr3  : ID
  1692.  
  1693.     With input:
  1694.  
  1695.         a+b*c
  1696.  
  1697.     The output would be:
  1698.  
  1699.          a <#1>  \+ <#2>  b <#3>  \* <#4>  c <#5>  NEWLINE <#6>
  1700.  
  1701.         zzd_ast called for <node #6>
  1702.         zzd_ast called for <node #5>
  1703.         zzd_ast called for <node #4>
  1704.         zzd_ast called for <node #3>
  1705.         zzd_ast called for <node #2>
  1706.         zzd_ast called for <node #1>
  1707.                                                                        Page 34
  1708.  
  1709.                                                                       (Item 105)
  1710. ##.  Suppose that one wanted to replace the terminal "+" with the rule:
  1711.  
  1712.         addOp  : "\+" | "-" ;
  1713.  
  1714. Then one would be unable to use the "make-a-root" operator because it can
  1715. be applied only to terminals.
  1716.  
  1717. There are two workarounds.  The #tokclass feature allows one to write:
  1718.  
  1719.         #tokclass AddOp { "\+" "\-"}
  1720.  
  1721. A #tokclass identifier may be used in a rule wherever a simple #token
  1722. identifier may be used.
  1723.  
  1724. The other workaround is much more complicated:
  1725.  
  1726.         expr    : (expr0 NEWLINE)
  1727.         ;expr0  : expr1 {"="^ expr0}
  1728.         ;expr1! : expr2 <<#0=#1;>>
  1729.                         (addOp expr2  <<#0=#(#1,#0,#2);>> )*
  1730.         ;expr2  : expr3 ("\*"^ expr3)*
  1731.         ;expr3  : ID
  1732.         ;addOp  : "\+" | "\-"
  1733.  
  1734.      With input:
  1735.  
  1736.         a-b-c
  1737.  
  1738.      The output is:
  1739.  
  1740.         ( \- <#4> ( \- <#2>  a <#1>  b <#3> ) c <#5> ) NEWLINE <#6>
  1741.  
  1742. The "!" for rule "expr1" disables automatic constructions of ASTs in the
  1743. rule.  This allows one to manipulate #0 manually.  If the expression had
  1744. no addition operator then the sub-rule "(addOp expr)*" would not be
  1745. executed and #0 will be assigned the AST constructed by rule expr2 (i.e.
  1746. AST #1).  However if there is an addOp present then each time the sub-rule
  1747. is rescanned due to the "(...)*" the current tree in #0 is placed as the
  1748. first of two siblings underneath a new tree.  This new tree has the AST
  1749. returned by addOp (AST #1 of the addOp sub-rule) as the root.
  1750.                                                                       (Item 106)
  1751. ##.  There is an option for doubly linked ASTs in the module ast.c. It is
  1752. controlled by #define zzAST_DOUBLE.  Even with zzAST_DOUBLE only the right
  1753. and down fields are filled while the AST tree is constructed.  Once the tree
  1754. is constructed the user must call the routine zzdouble_link(tree,NULL,NULL) to
  1755. traverse the tree and fill in the left and up fields. See page 12 of the
  1756. 1.06 manual for more information.
  1757.                                                                       (Item 107)
  1758. ##.  If a rule which creates an AST is called and the result is not
  1759. linked into the tree being constructed then zzd_ast() will not be called
  1760. to release the resources used by the rule.  Prior to version 1.20
  1761. this was especially important when rules were used in syntactic predicates.
  1762. Versions >= 1.20 bypasses construction of all ASTs during guess mode.
  1763.  
  1764.                                                                        Page 35
  1765. ===============================================================================
  1766. Section on Semantic Predicates
  1767. -------------------------------------------------------------------------------
  1768.                                                                       (Item 108)
  1769. ##.  There is a bug in 1.1x and 1.2x which prevents semantic predicates
  1770. from including string literals.  The predicate is incorrectly
  1771. "string-ized" in the call to zzfailed_predicate.
  1772.  
  1773.                 rule:  <<containsCharacter("!@#$%^&*",LATEXT(1))>>?  ID
  1774.                                         /*  Will not work */
  1775.  
  1776. The workaround is to place the literal in a string constant and use
  1777. the variable name.
  1778.                                                                       (Item 109)
  1779. ##.  There is a bug in 1.1x and 1.2x which prevents semantic predicates from
  1780. crossing lines unless one uses an escaped newline.
  1781.  
  1782.                 rule: <<do_test();\     /*** Note escaped newline ***/
  1783.                         this_works_in_120)>>? x y z;
  1784.                                                                       (Item 110)
  1785. ##.  Semantic predicates are enclosed in "<<... >>?"  but because they are
  1786. inside "if" statements they normally do not end with a ";" - unlike other
  1787. code enclosed in "<<...>>" in ANTLR.
  1788.                                                                       (Item 111)
  1789. ##.  If one leaves an extra space after the close of the action:
  1790.  
  1791.          <<...>> ? instead of <<...>>?
  1792.  
  1793. then ANTLR won't recognize it as a semantic predicate.
  1794.                                                                       (Item 112)
  1795. ##.  Init-actions are ignored as far as the hoisting of semantic predicates
  1796. is concerned.
  1797.                                                                        Page 36
  1798.  
  1799.                                                                       (Item 113)
  1800. ##.  Semantic predicates which are not the first element in the rule or
  1801. sub-rule become "validation predicates" and are not used for prediction.
  1802. After all, if there are no alternatives, then there is no need for
  1803. prediction - and alternatives exist only at the left edge of rules
  1804. and sub-rules.  Even if the semantic predicates are on the left edge it
  1805. is no guarantee that it will be part of the prediction expression.
  1806. Consider the following two examples:
  1807.  
  1808.         a  :  << LA(1)==ID ? propX(LATEXT(1)) : 1 >>?  ID glob  /* a1 */
  1809.            |  ID glob                                           /* a2 */
  1810.            ;
  1811.         b  :  << LA(1)==ID ? propX(LATEXT(1)) : 1 >>?  ID glob  /* b1 */
  1812.            |  NUMBER glob                                       /* b2 */
  1813.            ;
  1814.  
  1815. Rule a requires the semantic predicate to disambiguate alternatives
  1816. a1 and a2 because the rules are otherwise identical.  Rule b has a
  1817. token type of NUMBER in alternative b2 so it can be distinguished from
  1818. b1 without evaluation of the semantic predicate during prediction.  In
  1819. both cases the semantic predicate will also be evaluated inside the rule.
  1820.  
  1821. When the tokens which can follow a rule allow ANTLR to disambiguate the
  1822. expression without resort to semantic predicates ANTLR may not evaluate
  1823. the semantic predicate in the prediction code.  For example:
  1824.  
  1825.         simple_func   : <<LA(1)==ID ? isSimpleFunc(LATEXT(1)) : 1>>? ID
  1826.         complex_func  : <<LA(1)==ID ? isComplexFunc(LATEXT(1)) : 1>>? ID
  1827.  
  1828.         function_call : "("  ")"
  1829.  
  1830.         func : simple_func  function_call
  1831.              | complex_func "." ID function_call
  1832.  
  1833. In this case, a "simple_func" MUST be followed by a "(", and a
  1834. "complex_func" MUST be followed by a ".", so it is unnecessary to evaluate
  1835. the semantic predicates in order to predict which of the alternative to
  1836. use.  A simple test of the lookahead tokens is sufficient. As stated
  1837. before, the semantic predicates will still be used to validate the rule.
  1838.                                                                        Page 37
  1839.  
  1840.                                                                       (Item 114)
  1841. ##.  Suppose that the requirement that all semantic predicates which are
  1842. used in prediction expressions must appear at the left hand edge of a rule
  1843. were lifted?  Consider the following code segment:
  1844.  
  1845.         cast_expr                          /* a1  */
  1846.             : LP typedef RP cast_expr      /* a2  */
  1847.             | expr13                       /* a3  */
  1848.         ;expr13                            /* a4  */
  1849.             : id_name                      /* a5  */
  1850.             | LP cast_expr RP              /* a6  */
  1851.         ;typedef                           /* a7  */
  1852.             : <<LA(1)==ID ? isTypedefName(LATEXT(1)) : 1 >>? ID    /* a8  */
  1853.         ;id_name                           /* a9  */
  1854.             : ID                           /* a10 */
  1855.  
  1856. Now consider the token sequences:
  1857.  
  1858.         Token:  #1           #2               #3   #4
  1859.                 --   -----------------------  --   --
  1860.                 "("  ID-which-is-typedef     ")"   ID
  1861.                 "("  ID-which-is-NOT-typedef ")"
  1862.  
  1863. Were the semantic predicate at line a8 hoisted to predict which alternative
  1864. of cast_expr to use (a2 or a3) the program would use the wrong lookahead
  1865. token (LA(1) and LATEXT(1)) rather than LA(2) and LATEXT(2) to check for an
  1866. ID which satisfies "isTypedefName()".  This is because it is preceded by a
  1867. "(".   This problem could perhaps be solved by application of sufficient
  1868. ingenuity, however, in the meantime the solution is to rewrite the rules
  1869. so as to move the decision point to the left edge of the production.
  1870.  
  1871. First perform in-line expansion of expr13 (line a3) in cast_expr:
  1872.  
  1873.         cast_expr                          /* b1 */
  1874.             : LP typedef RP cast_expr      /* b2 */
  1875.             | id_name                      /* b3 */
  1876.             | LP cast_expr RP              /* b4 */
  1877.  
  1878. Secondly, move the alternatives (in cast_expr) beginning with LP to a
  1879. separate rule so that "typedef" and "cast_expr" will be on the left edge:
  1880.  
  1881.         cast_expr                          /* c1  */
  1882.             : LP cast_expr_suffix          /* c2  */
  1883.             | id_name                      /* c3  */
  1884.         ;cast_expr_suffix                  /* c4  */
  1885.             : typedef RP cast_expr         /* c5  */
  1886.             | cast_expr RP                 /* c6  */
  1887.         ;typedef                           /* c7  */
  1888.             : <<LA(1)==ID ? isTypedefName(LATEXT(1)) : 1 >>? ID    /* c8  */
  1889.         ;id_name                           /* c9  */
  1890.             : ID                           /* c10 */
  1891.  
  1892. This will result in the desired treatment of the semantic predicate to
  1893. choose from alternatives c5 and c6.
  1894.                                                                        Page 38
  1895.  
  1896.                                                                       (Item 115)
  1897. ##.  Validation predicates are evaluated by the parser.  If they fail a
  1898. call to zzfailed_predicate(string) is made.  To disable the message
  1899. redefine the macro zzfailed_predicate(string) or use the optional
  1900. "failed predicate" action which is enclosed in "[" and "]" and follows
  1901. immediately after the predicate:
  1902.  
  1903.         a : <<LA(1)==ID ?
  1904.               isTypedef(LATEXT(1)) : 1>>?[printf("Not a typedef\n");]
  1905.  
  1906. Douglas Cuthbertson (Douglas_Cuthbertson.JTIDS@jtids_qmail.hanscom.af.mil)
  1907. has pointed out that Antlr fails to put the fail action inside "{...}"
  1908. which can lead to problems when the action contains multiple statements.
  1909.                                                                       (Item 116)
  1910. ##.  An expression in a semantic predicate (e.g. <<isFunc()>>? ) should not
  1911. have side-effects. If there is no match then the rest of the rule using the
  1912. semantic predicate won't be executed.
  1913.                                                                        Page 39
  1914.  
  1915.                                                                       (Item 117)
  1916. ##.  What is the "context" of a semantic predicate ?  Answer due to TJP:
  1917.  
  1918. The context of a predicate is the set of k-strings (comprised of lookahead
  1919. symbols) that can be matched following the execution of a predicate.  For
  1920. example,
  1921.  
  1922.         a : <<p>>? alpha ;
  1923.  
  1924. The context of "p" is LOOK(alpha) where LOOK(alpha) is the set of
  1925. lookahead k-strings for alpha.
  1926.  
  1927. Normally, one should compute the context for ANTLR (manually) because
  1928. ANTLR is not smart enough to know the nature of your predicate and does not
  1929. know how much context information is needed; it's conservative and tries
  1930. to compute full LL(k) lookahead.  Normally, you only need one token:
  1931.  
  1932.         class_name: <<isClass(LATEXT(1))>>? ID ;
  1933.  
  1934. This example is incomplete, the predicate should really be:
  1935.  
  1936.         class_name: <<LA(1)==ID ? isClass(LATEXT(1)) : 1>>? ID ;
  1937.  
  1938. This says, "I can tell you something if you have an ID, otherwise
  1939. just assume that the rule is semantically valid."  This only makes a
  1940. difference if the predicate is *hoisted* out of the rule.  Here is an
  1941. example that won't work because it doesn't have context check in the
  1942. predicates:
  1943.  
  1944.         a   : ( class_name | NUM )
  1945.             | type_name
  1946.             ;
  1947.  
  1948.         class_name : <<isClass(LATEXT(1))>>? ID ;
  1949.  
  1950.         type_name :  <<isType(LATEXT(1))>>? ID ;
  1951.  
  1952. The prediction for production one of rule "a" will be:
  1953.  
  1954.         if ( LA(1) in { ID, NUM } && isClass(LATEXT(1)) ) { ...
  1955.  
  1956. Clearly, NUM will never satisfy isClass(), so the production will never
  1957. match.
  1958.  
  1959. When you ask ANTLR to compute context, it can check for missing predicates.
  1960. With -prc on, for this grammar:
  1961.  
  1962.         a   : b
  1963.             | <<isVar(LATEXT(1))>>?      ID
  1964.             | <<isPositive(LATEXT(1))>>? NUM
  1965.             ;
  1966.  
  1967.         b   : <<isType(LATEXT(1))>>?     ID
  1968.             |                            NUM
  1969.             ;
  1970.  
  1971. ANTLR reports:
  1972.  
  1973.         warning alt 1 of rule itself has no predicate to resolve
  1974.                                                  ambiguity upon \{ NUM \}
  1975.                                                                        Page 40
  1976.  
  1977.                                                                       (Item 118)
  1978. ##.  A documented restriction of ANTLR is the inability to hoist multiple
  1979. semantic predicates.  However, no error message is given when one attempts
  1980. this.  When compiled with k=1 and ck=2 this generates inappropriate code
  1981. in "statement" when attempting to predict "expr":
  1982.  
  1983.         #header <<
  1984.  
  1985.         #include "charbuf.h"
  1986.  
  1987.         int     istypedefName (char *);
  1988.         int     isCommand (char *);
  1989.  
  1990.         >>
  1991.  
  1992.         #token  BARK
  1993.         #token  GROWL
  1994.         #token  ID
  1995.  
  1996.         statement
  1997.                 : expr
  1998.                 | declaration
  1999.         ;expr
  2000.                 : commandName BARK
  2001.                 | typedefName GROWL
  2002.         ;declaration
  2003.                 : typedefName BARK
  2004.         ;typedefName
  2005.                 : <<LA(1)==ID ? istypedefName(LATEXT(1)) : 1>>? ID
  2006.         ;commandName
  2007.                 : <<LA(1)==ID ? isCommand(LATEXT(1)) : 1>>? ID
  2008.         ;
  2009.  
  2010. The generated code resembles the following:
  2011.  
  2012.         void statement()
  2013.         {
  2014.                 if ( (LA(1)==ID) &&
  2015.                      (LA(2)==BARK || LA(2)==GROWL) &&
  2016.                      (  (LA(1)==ID ? isCommand(LATEXT(1)) : 1) ||
  2017.                         (LA(1)==ID ? istypedefName(LATEXT(1)) : 1)) ) {
  2018.                                 expr();
  2019.                 } else {
  2020.                   if ( (LA(1)==ID) &&
  2021.                        (LA(2)==BARK) &&
  2022.                        (LA(1)==ID ? istypedefName(LATEXT(1)) : 1)) ) {
  2023.                                 declaration();
  2024.                 } ...
  2025.  
  2026. The problem is that "<typdefname> BARK" will be passed to expr() rather
  2027. than declaration().
  2028.  
  2029. Some help is obtained by using leading actions to inhibit hoisting as
  2030. described in the next notes.  (Don't confuse leading actions with
  2031. init-actions.) However, omitting all semantic predicates in the prediction
  2032. expression doesn't help if one requires them to predict the rule.
  2033.                                                                        Page 41
  2034.  
  2035.                                                                       (Item 119)
  2036. ##.  Leading actions will inhibit the hoisting of semantic predicates into
  2037. the prediction of rules.
  2038.  
  2039.         expr_rhs
  2040.                 : <<;>> <<>>  expr0
  2041.                 | command
  2042.  
  2043. See the section about known bugs for a more complete example.
  2044.                                                                       (Item 120)
  2045. ##.  When using semantic predicates in ANTLR is is *IMPORTANT* to
  2046. understand what the "-prc on" ("predicate context computation")
  2047. option does and what "-prc off" doesn't do.  Consider the following
  2048. example:
  2049.  
  2050.                 +------------------------------------------------------+
  2051.                 | Note:  All examples in this sub-section are based on |
  2052.                 | code generated with -k=1 and -ck=1.                  |
  2053.                 +------------------------------------------------------+
  2054.  
  2055.         expr    : upper
  2056.                 | lower
  2057.                 | number
  2058.                 ;
  2059.  
  2060.         upper   : <<isU(LATEXT(1))>>? ID ;
  2061.         lower   : <<isL(LATEXT(1))>>? ID ;
  2062.         number  : NUMBER ;
  2063.  
  2064. With "-prc on" ("-prc off" is the default) the code for expr() to predict
  2065. upper() would resemble:
  2066.  
  2067.       if (LA(1)==ID && isU(LATEXT(1)) && LA(1)==ID) {   /* a1  */
  2068.                 upper(zzSTR);                           /* a2  */
  2069.         }                                               /* a3  */
  2070.         else {                                          /* a4  */
  2071.                 if (LA(1)==ID && isL(LATEXT(1)) && LA(1)==ID) {  /* a5  */
  2072.                         lower(zzSTR);                   /* a6  */
  2073.                 }                                       /* a7  */
  2074.                 else {                                  /* a8  */
  2075.                         if (LA(1)==NUMBER) {            /* a9  */
  2076.                                 zzmatch(NUMBER);        /* a10 */
  2077.                         }                               /* a11 */
  2078.                         else                            /* a12 */
  2079.                                 {zzFAIL();goto fail;}   /* a13 */
  2080.                 }                                       /* a14 */
  2081.         } ...
  2082.         ...
  2083.  
  2084.         *******************************************************
  2085.         ***                                                 ***
  2086.         *** Starting with version 1.20:                     ***
  2087.         ***   Predicate tests appear AFTER lookahead tests  ***
  2088.         ***                                                 ***
  2089.         *******************************************************
  2090.  
  2091. Note that each test of LATEXT(i) is guarded by a test of the token type
  2092. (e.g. "LA(1)==ID && isU(LATEXT(1)").
  2093.  
  2094.                                                                        Page 42
  2095. With "-prc off" the code would resemble:
  2096.  
  2097.      if (isU(LATEXT(1)) && LA(1)==ID) {             /* b1  */
  2098.                 upper(zzSTR);                       /* b2  */
  2099.         }                                           /* b3  */
  2100.         else {                                      /* b4  */
  2101.                 if (isL(LATEXT(1)) && LA(1)==ID) {  /* b5  */
  2102.                         lower(zzSTR);               /* b6  */
  2103.                 }                                   /* b7  */
  2104.                 else {                              /* b8  */
  2105.                         if ( (LA(1)==NUMBER) ) {    /* b9  */
  2106.                                 zzmatch(NUMBER);    /* b10 */
  2107.                         }                           /* b11 */
  2108.                         else                        /* b12 */
  2109.                                 {zzFAIL();goto fail;}       /* b13 */
  2110.                 }                                   /* b14 */
  2111.         } ...
  2112.         ...
  2113.  
  2114. Thus when coding the grammar for use with "-prc off" it is necessary
  2115. to do something like:
  2116.  
  2117.         upper   : <<LA(1)==ID && isU(LATEXT(1))>>? ID ;
  2118.         lower   : <<LA(1)==ID && isL(LATEXT(1))>>? ID ;
  2119.  
  2120. This will make sure that if the token is of type NUMBER that it is not
  2121. passed to isU() or isL() when using "-prc off".
  2122.  
  2123. So, you say to yourself, "-prc on" is good and "-prc off" is bad. Wrong.
  2124.  
  2125. Consider the following slightly more complicated example in which the
  2126. first alternative of rule "expr" contains tokens of two different types:
  2127.  
  2128.         expr    : ( upper | NUMBER ) NUMBER
  2129.                 | lower
  2130.                 | ID
  2131.                 ;
  2132.  
  2133.         upper   : <<LA(1)==ID && isU(LATEXT(1))>>? ID ;
  2134.         lower   : <<LA(1)==ID && isL(LATEXT(1))>>? ID ;
  2135.         number  : NUMBER ;
  2136.  
  2137. With "-prc off" the code would resemble:
  2138.  
  2139.         ...
  2140.         {                                                 /* c1  */
  2141.         if (LA(1)==ID && isU(LATEXT(1)) &&                /* c2  */
  2142.              ( LA(1)==ID || LA(1)==NUMBER) ) {            /* c3  */
  2143.                 {                                         /* c4  */
  2144.                         if (LA(1)==ID) {                  /* c5  */
  2145.                                 upper(zzSTR);             /* c6  */
  2146.                         }                                 /* c7  */
  2147.                         else {                            /* c8  */
  2148.                                 if (LA(1)==NUMBER) {      /* c9  */
  2149.                                         zzmatch(NUMBER);  /* c10 */
  2150.                                 }                         /* c11 */
  2151.                                 else {zzFAIL();goto fail;}/* c12 */
  2152.                         }                                 /* c13 */
  2153.                 } ...
  2154.         ...
  2155.  
  2156.                                                                        Page 43
  2157. Note that if the token is a NUMBER (i.e. LA(1)==NUMBER) then the clause at
  2158. line c2 ("LA(1)==ID && ...") will always be false, which implies that the
  2159. test in the "if" statement (lines c2/c3) will always be false. (In other
  2160. words LA(1)==NUMBER implies LA(1)!=ID).  Thus the sub-rule for NUMBER at
  2161. line c9 can never be reached.
  2162.  
  2163. With "-prc on" essentially the same code is generated, although it
  2164. is not necessary to manually code a test for token type ID preceding
  2165. the call to "isU()".
  2166.  
  2167. The workaround is to to bypass the heart of the  predicate when
  2168. testing the wrong type of token.
  2169.  
  2170.         upper   : <<LA(1)==ID ? isU(LATEXT(1)) : 1>>? ID ;
  2171.         lower   : <<LA(1)==ID ? isL(LATEXT(1)) : 1>>? ID ;
  2172.  
  2173. Then with "-prc off" the code would resemble:
  2174.         ...
  2175.         {                                           /* d1  */
  2176.         if ( (LA(1)==ID ? isU(LATEXT(1)) : 1) &&    /* d2  */
  2177.                 (LA(1)==ID || LA(1)==NUMBER) ) {    /* d3  */
  2178.                 ...
  2179.         ...
  2180.  
  2181. With this correction the body of the "if" statement is now reachable
  2182. even if the token type is NUMBER - the "if" statement does what one
  2183. wants.
  2184.  
  2185. With "-prc on" the code would resemble:
  2186.  
  2187.         ...                                       /* e1 */
  2188.         if (LA(1)==ID &&                          /* e2 */
  2189.              (LA(1)==ID ? isU(LATEXT(1)) : 1) &&  /* e3 */
  2190.              (LA(1)==ID || LA(1)==NUMBER) ) {     /* e4 */
  2191.                 ...
  2192.         ...
  2193.  
  2194. Note that the problem of the unreachable "if" statement body has
  2195. reappeared because of the redundant test ("e2") added by the predicate
  2196. computation.
  2197.  
  2198. The lesson seems to be: when using rules which have alternatives which
  2199. are "visible" to ANTLR (within the lookahead distance) that have different
  2200. token types it is probably dangerous to use "-prc on".
  2201.                                                                        Page 44
  2202.  
  2203.                                                                       (Item 121)
  2204. ##.  You cannot use downward inheritance to pass parameters
  2205. to semantic predicates which are NOT validation predicates.  The
  2206. problem appears when the semantic predicate is hoisted into a
  2207. parent rule to predict which rule to call:
  2208.  
  2209. For instance:
  2210.  
  2211.         a :  b1 [flag]
  2212.           |  b2
  2213.           |  b3
  2214.  
  2215.         b1 [int flag]
  2216.           : <<LA(1)==ID && flag && hasPropertyABC (LATEXT(1))>>? ID ;
  2217.  
  2218.         b2 :
  2219.           : <<LA(1)==ID && hasPropertyXYZ (LATEXT(1))>>? ID ;
  2220.  
  2221.         b3 : ID ;
  2222.  
  2223. When the semantic predicate is evaluated within rule "a" to determine
  2224. whether to call b1, b2, or b3 the compiler will discover that there
  2225. is no variable named "flag" for procedure "a()".  If you are unlucky
  2226. enough to have a variable named "flag" in a() then you will have a
  2227. VERY difficult-to-find bug.
  2228.  
  2229. The -prc option has no effect on this behavior.
  2230.  
  2231. It is possible that a leading action (init-actions are ignored for purposes
  2232. of hoisting) will inhibit the hoisting of the predicate and make this code
  2233. work.  I have not verified this with versions 1.2x.
  2234.                                                                       (Item 122)
  2235. ##.  Another reason why semantic predicates must not have side effects is
  2236. that when they are hoisted into a parent rule in order to decide which
  2237. rule to call they will be invoked twice: once as part of the prediction
  2238. and a second time as part of the validation of the rule.
  2239.  
  2240. Consider the example above of upper and lower.  When the input does
  2241. in fact match "upper" the routine isU() will be called twice: once inside
  2242. expr() to help predict which rule to call, and a second time in upper() to
  2243. validate the prediction.  If the second test fails the macro zzpred_fail()
  2244. is called.
  2245.  
  2246. As far as I can tell, there is no simple way to disable the use of a
  2247. semantic predicate for validation after it has been used for prediction.
  2248.                                                                        Page 45
  2249.  
  2250.                                                                       (Item 123)
  2251. ##.  I had a problem in which I needed to do a limited amount of
  2252. lookahead, but didn't want to use all the machinery of syntactic
  2253. predicates.  I found that I could enlarge the set of expressions accepted
  2254. by "expr" and then look at the AST created in order to determined what
  2255. rules could follow:
  2256.  
  2257.         cast_expr                                                 /* a1  */
  2258.                 : <<int isCast=0;>>                               /* a2  */
  2259.                                                                   /* a3  */
  2260.                 LP! predefined_type RP! cast_expr                 /* a4  */
  2261.                         <<#0=#(toAST(T_cast),#0);>>               /* a5  */
  2262.                 | LP! expr0 RP!                                   /* a6  */
  2263.                         <<if ((#2->token)==T_class_name) {        /* a7  */
  2264.                              isCast=1;                            /* a8  */
  2265.                           } else {                                /* a9  */
  2266.                              isCast=0;                            /* a10 */
  2267.                           };                                      /* a11 */
  2268.                         >>                                        /* a12 */
  2269.                         ( <<;>> <<isCast==1>>?                    /* a13 */
  2270.                                 <<printf ("\nIs cast expr\n");>>  /* a14 */
  2271.                                 cast_expr                         /* a15 */
  2272.                                 <<#0=#(toAST(T_cast),#0);>>       /* a16 */
  2273.                                                                   /* a17 */
  2274.                         | <<printf ("\nIs NOT cast expr\n");>>    /* a18 */
  2275.                                 () /* empty */                    /* a19 */
  2276.                         )                                         /* a20 */
  2277.                 | unary_expr                                      /* a21 */
  2278.  
  2279. Later on I gave up on this approach and decided to use syntactic
  2280. predicates anyway.  It not only solved this problem, but others
  2281. where it was more difficult to patch up the grammar.  I can't bring
  2282. myself to remove the example, though.
  2283.  
  2284.                                                                        Page 46
  2285. ===============================================================================
  2286. Section on Syntactic Predicates (also known as "Guess Mode")
  2287. -------------------------------------------------------------------------------
  2288.                                                                       (Item 124)
  2289. ##.  The terms "infinite lookahead", "guess mode","syntactic predicates"
  2290. are all equivalent.  Sometimes the term "backtracking" is used as well,
  2291. although " backtracking" can sometimes be used to discuss lexing and DLG
  2292. as well.  The term "syntactic predicate" emphasizes that is handled by the
  2293. parser. The term "guess mode" emphasizes that the parser may have to
  2294. backtrack.  The term "infinite lookahead" emphasizes the implementation in
  2295. ANTLR: the entire input is read, processed, and tokenized by DLG before
  2296. ANTLR begins parsing.
  2297.                                                                       (Item 125)
  2298. ##.  An expression in a syntactic predicate should not have side-effects.
  2299. If there is no match then the rule which uses the syntactic predicate won't be
  2300. executed.
  2301.                                                                       (Item 126)
  2302. ##.  In some extremely unusual cases a user wants side-effects during guess
  2303. mode.  In this case one can use exploit the fact that Antlr always
  2304. executes init-actions, even when in guess mode:
  2305.  
  2306.         rule  : (guess)? A
  2307.               | B
  2308.               ;
  2309.         guess : <<regular-init-action-that's-always-executed>>
  2310.                 A ( <<init-action-for-empty-subrule>> ) B
  2311.               ;
  2312.  
  2313. The init-action in the sub-rule will always be executed, even in guess-mode.
  2314. Contributed by TJP.
  2315.                                                                       (Item 127)
  2316. ##.  When using syntactic predicates the entire input buffer is read and
  2317. tokenized by DLG before parsing by ANTLR begins.  If a "wrong" guess
  2318. requires that parsing be rewound to an earlier point all attributes
  2319. that were creating during the "guess" are destroyed and the parsing
  2320. begins again and it creates new attributes at it reparses the (previously)
  2321. tokenized input.
  2322.                                                                       (Item 128)
  2323. ##.  In infinite lookahead mode the line and column information is
  2324. hopelessly out-of-sync because zzline will contain the line number of
  2325. the last line of input - the entire input was parsed before
  2326. scanning was begun.  The line and column information is not restored
  2327. during backtracking.  To keep track of the line information in a meaningful
  2328. way one has to use the ZZINF_LINE macro which was added to pccts in version
  2329. 1.20.
  2330.  
  2331. Putting line and column information in a field of the attribute will not
  2332. help.  The attributes are created by ANTLR, not DLG, and when ANTLR
  2333. backtracks it destroys any attributes that were created in making the
  2334. incorrect guess.
  2335.                                                                       (Item 129)
  2336. ##.  As infinite lookahead mode causes the entire input to be scanned
  2337. by DLG before ANTLR begins parsing, one cannot depend on feedback from
  2338. the parser to the lexer to handle things like providing special token codes
  2339. for items which are in a symbol table (the "lex hack" for typedefs
  2340. in the C language).  Instead one MUST use semantic predicates which allow
  2341. for such decisions to be made by the parser.
  2342.                                                                       (Item 130)
  2343. ##.  One cannot use an interactive scanner (ANTLR -gk option) with the
  2344. ANTLR infinite lookahead and backtracking options (syntactic predicates).
  2345.                                                                        Page 47
  2346.  
  2347.                                                                       (Item 131)
  2348. ##.  An example of the need for syntactic predicates is the case where
  2349. relational expressions involving "<" and ">"  are enclosed in angle bracket
  2350. pairs.
  2351.  
  2352.         Relation:    a < b
  2353.         Array Index: b <i>
  2354.         Problem:     a < b<i>
  2355.                  vs. b < a>
  2356.  
  2357. I was going to make this into an extended example, but I haven't had
  2358. time yet.
  2359.                                                                       (Item 132)
  2360. ##. Version 1.20 fixes a problem in 1.10 in which ASTs were constructed
  2361. during guess mode.  In version 1.10 care had to be taken to deallocate the
  2362. ASTs that were created in the rules which were invoked in guess mode.
  2363.                                                                       (Item 133)
  2364. ##.  The following is an example of the use of syntactic predicates.
  2365.  
  2366.         program : ( s SEMI )* ;
  2367.  
  2368.         s       : ( ID EQUALS )? ID EQUALS e
  2369.                   | e
  2370.                   ;
  2371.  
  2372.         e       : t ( PLUS t | MINUS t )* ;
  2373.  
  2374.         t       : f ( TIMES f | DIV f )* ;
  2375.  
  2376.         f       : Num
  2377.                   | ID
  2378.                   | "\(" e "\)"
  2379.                   ;
  2380.  
  2381. When compiled with k=1:
  2382.  
  2383.         antlr -fe err.c -fh stdpccts.h -fl parser.dlg -ft tokens.h \
  2384.                  -fm mode.h -k 1 test.g
  2385.  
  2386. One gets the following warning:
  2387.  
  2388.    warning: alts 1 and 2 of the rule itself ambiguous upon { ID }
  2389.  
  2390. even though the manual suggests that this is okay.  The only problem is
  2391. that ANTLR 1.10 should NOT issue this error message unless the -w2 option
  2392. is selected.
  2393.  
  2394. Included with permission of S. Salters
  2395.  
  2396.                                                                        Page 48
  2397. ===============================================================================
  2398. Section on Inheritance
  2399. -------------------------------------------------------------------------------
  2400.                                                                       (Item 134)
  2401. ##.  A rule which uses upward inheritance:
  2402.  
  2403.         rule > [int result] :  x | y | z;
  2404.  
  2405. Is simply declaring a function which returns an "int" as a function
  2406. value.  If the function has more than one item passed via upward
  2407. inheritance then ANTLR creates a structure to hold the result and
  2408. then copies each component of the structure to the upward inheritance
  2409. variables.
  2410.                                                                       (Item 135)
  2411. ##.  When writing a rule that uses downward inheritance:
  2412.  
  2413.         rule [int *x] : r1 r2 r3
  2414.  
  2415. one should remember that the arguments passed via downward inheritance are
  2416. simply arguments to a function.  If one is using downward inheritance
  2417. syntax to pass results back to the caller (really upward inheritance !)
  2418. then it is necessary to pass the address of the variable which will receive
  2419. the result.
  2420.                                                                       (Item 136)
  2421. ##.  ANTLR is smart enough to combine the declaration for an AST with
  2422. the items declared via downward inheritance when constructing the
  2423. prototype for a function which uses both ASTs and downward inheritance.
  2424.  
  2425.                                                                        Page 49
  2426. ===============================================================================
  2427. Section on LA, LATEXT, NLA, and NLATEXT
  2428. -------------------------------------------------------------------------------
  2429.                                                                       (Item 137)
  2430. ##.  Do not use LA(i) or LATEXT(i) in the action routines of #token
  2431. statements.  To refer to the token code (in a #token action) of the token
  2432. just recognized use "NLA". NLA is an lvalue (can appear on the left hand
  2433. side of an assignment statement).  To refer to the text just recognized
  2434. use zzlextext (the entire text), NLATEXT. One can also use
  2435. zzbegexpr/zzendexpr which refer to the regular expression just matched.
  2436. The char array pointed to by zzlextext may be larger than the string
  2437. pointed to by zzbegexpr and zzendexpr because it includes substrings
  2438. accumulated through the use of zzmore().
  2439.                                                                       (Item 138)
  2440. ##.  Extra care must be taken in using LA(i) and LATEXT(i) when in
  2441. interactive mode (Antlr switch -gk) because Antlr doesn't guarantee that
  2442. it will fetch lookahead tokens until absolutely necessary. It is somewhat
  2443. safer to refer to lookahead information in semantic predicates, but care
  2444. is still required.  I have summarized the output from Example 7:
  2445.  
  2446. -----------------------------------------------------------------------
  2447.                 k=1         k=1        k=3        k=3         k=3
  2448.                 standard  infinite   standard  interactive  infinite
  2449. -----------------------------------------------------------------------
  2450. for a semantic predicate
  2451. ------------------------
  2452.   LA(0)         Next        Next       --         --           --
  2453.   LA(1)         Next        Next      Next       Next         Next
  2454.   zzlextext     Next        Next      Next        --          Next
  2455.   ZZINF_LA(0)               Next                              Next
  2456.   ZZINF_LA(1)               NextNext                          NextNext
  2457. -----------------
  2458. for a rule action
  2459. -----------------
  2460.   LA(0)         Prev        Prev       --        Prev          --
  2461.   LA(1)         Prev        Prev      Prev       Next         Prev
  2462.   zzlextext     Prev        Prev      Prev        --          Prev
  2463.   ZZINF_LA(0)               Prev                              Prev
  2464.   ZZINF_LA(1)               Next                              Next
  2465. -----------------------------------------------------------------------
  2466.  
  2467. The entries "prev" and "next" means that the left hand item refers to the
  2468. token which precedes (or follows) the action which generated the output.
  2469.  
  2470. For semantic predicate entries think of the following rule:
  2471.  
  2472.         rule : <<semantic-predicate>>? Next NextNext;
  2473.  
  2474. For rule-action entries think of the following rule:
  2475.  
  2476.         rule : Prev <<action>> Next NextNext;
  2477.                                                                       (Item 139)
  2478. ##.  Example 7 below gives some diagnostic output for a k=3 grammar compiled
  2479. with "standard" options, interactive options (AFLAGS=-gk), and infinite
  2480. lookahead option (CFLAGS=-DZZINF_LOOK).
  2481.                                                                       (Item 140)
  2482. ##.  Example 8 shows how to modify the lookahead token NLA.
  2483.                                                                        Page 50
  2484.  
  2485.                                                                       (Item 141)
  2486. ##.  I find it helpful to think of lexical processing by DLG as a process
  2487. which fills a pipeline and of Antlr as a process which empties a pipeline.
  2488. (This relationship is exposed in C++ mode because DLG passes an object of
  2489. a certain class to Antlr).
  2490.  
  2491. With LL_K=1 the pipeline is only one item deep and is trivial and pretty much
  2492. invisible. It is invisible because one can make a decision in Antlr which
  2493. affects how the very next token is processed.  For instance with LL_K=1 it is
  2494. possible to change the DLG mode in an Antlr action with zzmode() and have
  2495. the next token (the one following the one just parsed by Antlr) parsed
  2496. according to the new #lexclass.
  2497.  
  2498. With LL_K>1 the pipeline is not invisible.  DLG will put a number of tokens
  2499. into the pipeline and Antlr will analyze them in the same order.  How many
  2500. tokens are in the pipeline depends on options one has chosen.
  2501.  
  2502. Case 1: If one has infinite lookahead mode ("(...)?") (also known as
  2503. syntactic predicates) then the pipeline is as huge as the input stream
  2504. since the entire input is tokenized by DLG before Antlr even begins
  2505. analysis.
  2506.  
  2507. Case 2: If you have demand lookahead (interactive mode) then you'll have a
  2508. varying amount of lookahead depending on how much Antlr thinks it needs to
  2509. parse the thing it is working on.  This may be zero (or maybe its 1 token)
  2510. up to k tokens.  Naturally it takes extra work by Antlr to keep track of
  2511. how many tokens are in the pipe and how many are needed to parse the next
  2512. rule.
  2513.  
  2514. Case 3: In "normal" mode DLG tries to stay exactly k tokens ahead of
  2515. Antlr.  This is a half-truth.  It rounds k up to the next power of
  2516. 2 so that with k=3 it actually has a pipeline of 4 tokens. If one says
  2517. "k=3" the analysis is still k=3, but the pipeline size is rounded up
  2518. because TJP decided it was better to use a bit-wise "and" then some other
  2519. mechanism to compute (n+1) mod k - where n is the position in a circular
  2520. buffer.
  2521.  
  2522.                                                                        Page 51
  2523. ===============================================================================
  2524. Section on Prototypes
  2525. -------------------------------------------------------------------------------
  2526.                                                                       (Item 142)
  2527. ##.  Prototype for typical create_attr routine:
  2528.  
  2529.      #define zzcr_attr(attr,token,text) \
  2530.                 create_attr(attr,token,text)
  2531.  
  2532.      void create_attr (Attrib *attr,int token,char *text);
  2533.                                                                       (Item 143)
  2534. ##.  Prototype for a typical create_ast routine invoked to automatically
  2535. construct an AST from an attribute:
  2536.  
  2537.      #define zzcr_ast(ast,attr,tok,astText) \
  2538.           create_ast(ast,attr,tok,text)
  2539.  
  2540.      void create_ast (AST *ast,Attr *attr,int tok,char *text);
  2541.                                                                       (Item 144)
  2542. ##.  Prototype for a typical make_ast routine invoked by the #[...]
  2543. notation.
  2544.  
  2545.      AST *zzmk_ast (AST *ast,int token,char *text)
  2546.                                                                       (Item 145)
  2547. ##.  Prototype for a typical zzd_ast macro which is invoked when destroying
  2548. an AST node:
  2549.  
  2550.      #define zzd_ast(node) delete_ast(node)
  2551.  
  2552.      void delete_ast (AST * node);
  2553.                                                                       (Item 146)
  2554. ##.  Prototype for zzdef0 macro to initialize $0 of a rule:
  2555.  
  2556.      #define zzdef0(attr) define_attr_0 (attr)
  2557.  
  2558.      void define_attr_0 (Attrib *attr);
  2559.                                                                       (Item 147)
  2560. ##.  Prototype for ANTLR (these are actually macros):
  2561.  
  2562.      read from file:     void ANTLR   (void startRule(...),FILE *)
  2563.      read from string:   void ANTLRs  (void startRule(...),zzchar_t *)
  2564.      read from function: void ANTLRf  (void startRule(...),int (*)())
  2565.      read from file:     void ANTLRm
  2566.                           (void startRule(...),FILE *,int lexclass)
  2567.  
  2568.              In the call to ANTLRf the function behaves like getchar()
  2569.              in that it returns EOF (-1) to indicate end-of-file.
  2570.  
  2571.      If ASTs are used or there is downward or upward inheritance then the
  2572.      call to the startRule must pass these arguments:
  2573.  
  2574.                 AST     *root;
  2575.                 ANTLRf (startRule(&root),stdin);
  2576.  
  2577.                                                                        Page 52
  2578. ===============================================================================
  2579. Section on ANTLR/DLG Internals and Routines That Might Be Useful
  2580. -------------------------------------------------------------------------------
  2581.                 ****************************
  2582.                 ****************************
  2583.                 **                        **
  2584.                 **  Use at your own risk  **
  2585.                 **                        **
  2586.                 ****************************
  2587.                 ****************************
  2588.                                                                       (Item 148)
  2589. ##.  Sometimes I have wanted to add code which appears before every
  2590. #token action or after every #token action.  Rather than modify every
  2591. #token statement one could add code to pccts/h/dlgauto.h near line 430:
  2592.  
  2593.                 (*actions)[accepts[state]]();
  2594.  
  2595. This statement is executed for every #token statement.  Even #token
  2596. statements without a user-written action contain the required action:
  2597.  
  2598.                 NLA=TokenIdentifier
  2599.  
  2600. Following the statement near line 430 of dlgauto.h would be an appropriate
  2601. place to insert debug code to print out token definitions.  The name
  2602. for token "i" is in the char * array zztokens[i] (defined in antlr.h).
  2603.                                                                       (Item 149)
  2604. ##.  static int zzauto - defined in dlgauto.h
  2605.  
  2606.      Current DLG mode.  This is used by zzmode() only.
  2607.                                                                       (Item 150)
  2608. ##.  void zzerr (char * s) defined in dlgauto.h
  2609.  
  2610.      Defaults to zzerrstd(char *s) in dlgauto.h
  2611.  
  2612.      Unless replaced by a user-written error reporting routine:
  2613.  
  2614.              fprintf(stderr,
  2615.                         "%s near line %d (text was '%s')\n",
  2616.                         ((s == NULL) ? "Lexical error" : s),
  2617.                         zzline,zzlextext);
  2618.  
  2619.      This should probably be "void zzerr (const char * s)".
  2620.                                                                       (Item 151)
  2621. ##.  static char zzebuf[70] defined in dlgauto.h
  2622.  
  2623.                                                                        Page 53
  2624. ===============================================================================
  2625. Section on Known Minor Bugs in pccts (in reverse chronological order)
  2626. -------------------------------------------------------------------------------
  2627.                                                                       (Item 152)
  2628. ##.  The fail action following a semantic predicate is not enclosed
  2629. in "{...}". This can lead to problems when the fail action contains
  2630. more than one statement.  Reported by Douglas Cuthbertson
  2631. (Douglas_Cuthbertson.JTIDS@jtids_qmail.hanscom.af.mil).
  2632.                                                                       (Item 153)
  2633. ##.  The UPDATE.120 of (1-Apr-94) reports that there are problems in
  2634. combining guess mode and semantic predicates under some circumstances.
  2635.  
  2636.                                                                        Page 54
  2637. ===============================================================================
  2638. Ideas on the Construction of ASTs and their use with Sorcerer
  2639. -------------------------------------------------------------------------------
  2640. Consider the problem of a grammar which would normally require two
  2641. passes through the source code to properly analyze.  In some cases
  2642. it is convenient to perform a first pass which creates AST trees
  2643. and perform the second pass by analyzing the AST trees with Sorcerer.
  2644.  
  2645. 1) Define an AST node that contains the information you'll need in the
  2646. second pass.  For example,
  2647.  
  2648. /*
  2649.  * Parse trees are represented by an abstract-syntax-tree (AST)
  2650.  * (forward declare the pointer here). Refer to parse.h for description
  2651.  * of parse_info.
  2652.  */
  2653. typedef struct parse_struct *ast_ref;
  2654.  
  2655. /* parser attributes ($-symbols) & AST nodes */
  2656. typedef struct parse_struct *pinfo_ref;
  2657.  
  2658. /*
  2659.  * the parse structure is used to describe both attributes and
  2660.  * AST nodes
  2661.  */
  2662.  
  2663. struct parse_struct {
  2664.     pinfo_ref   right;             /* points to siblings */
  2665.     pinfo_ref   down;              /* points to children */
  2666.     int         token;             /* token number (see tokens.h) */
  2667.     char        *text;             /* input text */
  2668.     src_pos     pos;               /* position in source file */
  2669.     object_ref  obj;               /* object description (id's) */
  2670.     type_ref    typ;               /* type description (expr's) */
  2671.     const_value value;             /* value of a constant expression */
  2672.     } ;
  2673.  
  2674. /*
  2675.  * define Abstract Syntax Tree (AST) nodes
  2676.  */
  2677.  
  2678. /* ast_ref was forward-defined */
  2679. typedef struct parse_struct AST;
  2680.  
  2681. /*
  2682.  * the Pass-1 (parse phase) parse-attributes ($-variables)
  2683.  * have the same structure as an AST node.
  2684.  */
  2685. typedef struct parse_struct Attrib, *Attrib_ref;
  2686.  
  2687.  
  2688. In the code above, the parse-attribute was defined to have the same
  2689. structure as an AST node.  This isn't a requirement, but just makes it
  2690. easier to pass information produced in the first pass on to subsequent
  2691. passes.
  2692.  
  2693.                                                                        Page 55
  2694. 2) Have the first pass build a symbol table as it parses the input, perform
  2695. semantic checks, and build an AST.  Use the -gt (generate tree) option on
  2696. ANTLR, and override the automatically generated tree construction operations
  2697. as needed.  For example,
  2698.  
  2699. var_declare:
  2700.         << pvec_ref v_list;
  2701.            int i;
  2702.            boolean has_var_section = FALSE;
  2703.         >>
  2704.         VAR^
  2705.         (
  2706.         var_id_list > [v_list] COLON
  2707.           { extern_kw
  2708.             | static_kw
  2709.           }
  2710.         type
  2711.         <<
  2712.         for (i = 0; i < v_list->len; ++i) {
  2713.             object_ref v = (object_ref) v_list->val[i];
  2714.             define_var(v, $4.typ);
  2715.         }
  2716.         >>
  2717.           { ASSIGNMENT expr
  2718.             << mark_var_use(#2, VAR_RHS); >>
  2719.           }
  2720.         SEMI
  2721.         << free_pvec(v_list); >>
  2722.         )+
  2723.         ;
  2724. var_id_list > [pvec_ref v_list]:
  2725.         << object_ref this_var;
  2726.            $v_list = new_pvec();
  2727.         >>
  2728.         ID
  2729.         << this_var = new_var_id(&$1);
  2730.            if (this_var != NULL) append_pvec($v_list, (void *)this_var);
  2731.         >>
  2732.         (
  2733.         COMMA ID
  2734.         << this_var = new_var_id(&$2);
  2735.            if (this_var != NULL) append_pvec($v_list, (void *)this_var);
  2736.         >>
  2737.         )*
  2738.         ;
  2739.  
  2740. The "pvec" stuff above is just a vector of pointers that can be
  2741. extended automatically. A linked list would work just as well.  The
  2742. idea is that we must first collect the declared variables, then
  2743. parse the type declaration, then apply bind the type to the declared
  2744. variables.  We used ANTLR's auto-tree-generation mode, and didn't
  2745. override its actions with our own.  Therefore, the following Sorcerer
  2746. fragment will recognize the AST  built for a variable declaration:
  2747.  
  2748.                                                                        Page 56
  2749. var_declare:
  2750.         #( VAR
  2751.           ( v_list: var_id_list COLON
  2752.             { EXTERN | STATIC }
  2753.             type
  2754.             { ASSIGNMENT expr }
  2755.             SEMI
  2756.           )+
  2757.         )
  2758.         ;
  2759. var_id_list:
  2760.         ID ( COMMA ID)*
  2761.         ;
  2762.  
  2763. Here's an example, where we use explicit rules to build an AST:
  2764.  
  2765. expr!:
  2766.         simple_expr
  2767.         << $expr = $1; #0 = #1; >>
  2768.         ( rel_op simple_expr
  2769.           << parse_binary_op(&$expr, &$1, &$2); #0 = #(NULL, #0, #1, #2); >>
  2770.         )*
  2771.         << $expr.token = EXPR;
  2772.            $expr.text = "expr";
  2773.            #0 = #(#[&$expr], #0);
  2774.         >>
  2775.         ;
  2776.  
  2777. The construct, #[&$expr] first takes the address of the $expr
  2778. attribute (attributes are structures, not pointers, in this example),
  2779. and then applies the #[] operation which makes a call to the routine
  2780. that creates an AST node, given an attribute (or attribute address
  2781. in our case).  It takes a while to get the hang of where the &'s
  2782. #'s, and $'s go, but can be a real time-saver once you master it.
  2783. What we're doing above is building a special EXPR (expression) node.
  2784. This node would be parsed as follows in subsequent passes, using
  2785. Sorcerer:
  2786.  
  2787. expr:   #( e: EXPR
  2788.            l_oprnd: simple_expr  << e->typ = l_oprnd->typ; >>
  2789.              (op: rel_op  r_oprnd: simple_expr
  2790.                   <<
  2791.                       e->typ = std_bool_type->obj_type;
  2792.                       if (op->token == IN) {
  2793.                           /* no type conversion checking for IN.
  2794.                            * try to rewrite simple IN ops.
  2795.                            */
  2796.                           if (is_simple_in_op(l_oprnd, op, r_oprnd)) {
  2797.                               rewrite_simple_in_op(l_oprnd, op, r_oprnd);
  2798.                           }
  2799.                       } else {
  2800.                           cvt_term(&l_oprnd, op, r_oprnd, _t);
  2801.                       }
  2802.                   >>
  2803.              )*
  2804.         );
  2805.  
  2806.                                                                        Page 57
  2807. We left in the actual actions of the second (Sorcerer driven) pass.
  2808. Notice how the Sorcerer grammar labels various parts of the expr
  2809. node ("e", "l_oprnd", "op", and "r_oprnd").  This gives the second
  2810. pass access to each node, as it is recognized.
  2811.  
  2812. The second pass uses the "typ" field, which contains the type of
  2813. the ID, expression, or literal parsed by the first pass.  In the
  2814. actions above, we are propagating additional type information (for
  2815. example, the result of a relational op is always a boolean, checking
  2816. for implicit type conversions, and handling simple cases of Pascal's
  2817. IN operation).  The fragment above is from a Pascal to Ada translator,
  2818. so the translator has to make Pascal's implicit type conversions
  2819. between integer and real into explicit Ada type conversions, and
  2820. has to convert operations on sets (i.e. IN) into operations on
  2821. packed boolean arrays, in Ada, or calls to runtime routines.
  2822.  
  2823. Sometimes when you are building the AST for a given construct,
  2824. you need to use information gained from semantic analysis.  An
  2825. example is the "assignment" or "call" statement:
  2826.  
  2827. /*
  2828.  * If a variable access appears alone, then it must be either a call to
  2829.  * procedure with no parameters, or an indirection through a pointer
  2830.  * to a procedure with no parameters.
  2831.  */
  2832. assign_or_call_stmt!:
  2833.         << type_ref r_type = NULL;
  2834.            ast_ref v;
  2835.         >>
  2836.         variable
  2837.           << v = #1;
  2838.              $assign_or_call_stmt       = $1;
  2839.              $assign_or_call_stmt.token = PROC_CALL;
  2840.              $assign_or_call_stmt.text  = "proc_call";
  2841.              r_type = $assign_or_call_stmt.typ;
  2842.              if (v != NULL && v->obj != NULL
  2843.                  && v->obj->obj_result != NULL
  2844.                  && v->obj->obj_kind == func_obj
  2845.                  && v->down->token == ID
  2846.                  && v->down->right == NULL) {
  2847.                    object_ref func = v->obj;
  2848.                    /* function name used on left hand side;
  2849.                     * convert to reference to the function's return value
  2850.                     */
  2851.                    v->obj  = func->obj_result;
  2852.                    v->typ  = func->obj_result->obj_type;
  2853.                    v->down->text = func->obj_result->obj_name;
  2854.                    v->down->obj  = func->obj_result;
  2855.                    v->down->typ  = func->obj_result->obj_type;
  2856.              }
  2857.              #0 = v;
  2858.           >>
  2859.  
  2860.                                                                        Page 58
  2861.         { ASSIGNMENT expr
  2862.           << $assign_or_call_stmt.token = ASSIGNMENT;
  2863.              $assign_or_call_stmt.text  = ":=";
  2864.              mark_var_use(#2, VAR_RHS);
  2865.              mark_var_use(v, VAR_LHS);
  2866.              #0 = #(NULL, #0, #[&$1], #2);
  2867.           >>
  2868.           | ( LPAREN actual_param_list RPAREN
  2869.               << mark_actual_param_use(#2, r_type);
  2870.                  mark_var_use(v, VAR_RHS);
  2871.                  #0 = #(NULL, #0, #[&$1], #2, #[&$3]);
  2872.               >>
  2873.             )
  2874.         }
  2875.         << #0 = #( #[&$assign_or_call_stmt], #0); >>
  2876.         ;
  2877.  
  2878. The problem we're solving is that both an assignment statement and a
  2879. procedure call statement begin with a "variable".  Since ANTLR is
  2880. LL-based, this statement construct is "ambiguous" in that both statement
  2881. types (assignment and call) begin with the same non-terminal.  A
  2882. "variable" includes such operations as array subscripting, pointer
  2883. deferencing, and record field selection. Thus, a "variable" may comprise
  2884. an arbitrary number of tokens.
  2885.  
  2886. We might use syntactic predicates as a form a look-ahead to resolve the
  2887. two cases above, but instead I decided to make the assumption that we have
  2888. "PROC_CALL", and to correct that "guess" once we see the assignment
  2889. operation.  Thus, the above rule will build one of the following two AST
  2890. structures:
  2891.  
  2892. assign_stmt:
  2893.         #( ASSIGNMENT
  2894.         variable  ASSIGNMENT expr
  2895.         )
  2896.         ;
  2897. call_stmt:
  2898.         #( PROC_CALL
  2899.         variable {LPAREN actual_param_list RPAREN}
  2900.         )
  2901.         ;
  2902.  
  2903. In your AST, you might want to drop unnecessary syntactic tokens such as
  2904. ASSIGNMENT, LPAREN, RPAREN, COMMA, COLON, etc. We kept them, because we
  2905. thought it would be necessary for certain parts of source-to-source
  2906. translation.  We don't think that's true, any more, but have not gone back
  2907. and changed the AST structure either.
  2908.  
  2909.                                                                        Page 59
  2910. 3) Build a separate Sorcerer grammar file to recognize the AST that you
  2911. have built, and then add your second pass actions.  These actions will
  2912. access fields in the AST node, that were filled in by the first pass.  For
  2913. example, identifiers will probably have an "object_ref" that points to the
  2914. object named by the identifier, and expression (EXPR) nodes will have a
  2915. "typ" field that gives the expression's type. You might also add a "value"
  2916. field that gives the value of a literal, named literal, or statically
  2917. evaluated constant expression. See the code fragments above for some ideas
  2918. on how this is done.
  2919.  
  2920. Conclusions:
  2921.  
  2922.    1) You'll need an ANTLR (.g) description for pass1, and a separate
  2923.    Sorcerer (.sor) description for pass2.  Often the pass2 AST
  2924.    representation is much more regular and well-formed than the
  2925.    original text token stream used by pass1.
  2926.  
  2927.    2) It can be a bit intimidating putting the pieces together.
  2928.    Try it incrementally, trying a small subset of your larger
  2929.    problem.
  2930.  
  2931.    3) There are a lot of ways to go with how you represent
  2932.    attributes ($-variables), AST nodes, and the things that
  2933.    go on in various passes.  For example, you might have
  2934.    pass1 simply build the AST and perform *no* symbol definitions
  2935.    or semantic checks.  Then pass2 might walk the tree and build
  2936.    the symbol, and make various checks. Pass2 might also disambiguate
  2937.    cases that look syntactically similar, and can only be disambiguated
  2938.    using symbol definitions.  Then, you could have a pass3 (another
  2939.    Sorcerer driven tree-walk) that does the 'real work' of your
  2940.    compiler/translator.
  2941.  
  2942. Contributed by Gary Funck (gary@intrepid.com)
  2943.  
  2944.                                                                        Page 60
  2945. ===============================================================================
  2946. Example 1 of #lexclass
  2947. ===============================================================================
  2948. Borrowed code
  2949. -------------------------------------------------------------------------------
  2950. /*
  2951.  * Various tokens
  2952.  */
  2953. #token "[\t\ ]+"        << zzskip(); >> /* Ignore whitespace */
  2954. #token "\n"             << zzline++; zzskip(); >> /* Count lines */
  2955.  
  2956. #token "\""             << zzmode(STRINGS); zzmore(); >>
  2957. #token "'"              << zzmode(CHARACTERS); zzmore(); >>
  2958. #token "/\*"            << zzmode(COMMENT); zzskip(); >>
  2959. #token "//"             << zzmode(CPPCOMMENT); zzskip(); >>
  2960.  
  2961. /*
  2962.  * C++ String literal handling
  2963.  */
  2964. #lexclass STRINGS
  2965. #token STRING "\""      << zzmode(START); >>
  2966. #token "\\\""           << zzmore(); >>
  2967. #token "\\n"            << zzreplchar('\n'); zzmore(); >>
  2968. #token "\\r"            << zzreplchar('\r'); zzmore(); >>
  2969. #token "\\t"            << zzreplchar('\t'); zzmore(); >>
  2970. #token "\\[1-9][0-9]*"  << zzreplchar((char)strtol(zzbegexpr, NULL, 10));
  2971.                            zzmore(); >>
  2972. #token "\\0[0-7]*"      << zzreplchar((char)strtol(zzbegexpr, NULL, 8));
  2973.                            zzmore(); >>
  2974. #token "\\0x[0-9a-fA-F]*" << zzreplchar((char)strtol(zzbegexpr, NULL, 16));
  2975.                              zzmore(); >>
  2976. #token "\\~[\n\r]"      << zzmore(); >>
  2977. #token "[\n\r]"         << zzline++; zzmore(); /* Print warning */ >>
  2978. #token "~[\"\n\r\\]+"   << zzmore(); >>
  2979.  
  2980. /*
  2981.  * C++ Character literal handling
  2982.  */
  2983. #lexclass CHARACTERS
  2984. #token CHARACTER "'"    << zzmode(START); >>
  2985. #token "\\'"            << zzmore(); >>
  2986. #token "\\n"            << zzreplchar('\n'); zzmore(); >>
  2987. #token "\\r"            << zzreplchar('\r'); zzmore(); >>
  2988. #token "\\t"            << zzreplchar('\t'); zzmore(); >>
  2989. #token "\\[1-9][0-9]*"  << zzreplchar((char)strtol(zzbegexpr, NULL, 10));
  2990.                            zzmore(); >>
  2991. #token "\\0[0-7]*"      << zzreplchar((char)strtol(zzbegexpr, NULL, 8));
  2992.                            zzmore(); >>
  2993. #token "\\0x[0-9a-fA-F]*" << zzreplchar((char)strtol(zzbegexpr, NULL, 16));
  2994.                              zzmore(); >>
  2995. #token "\\~[\n\r]"      << zzmore(); >>
  2996. #token "[\n\r]"         << zzline++; zzmore(); /* Print warning */ >>
  2997. #token "~[\'\n\r\\]"    << zzmore(); >>
  2998.  
  2999.                                                                        Page 61
  3000. /*
  3001.  * C-style comment handling
  3002.  */
  3003. #lexclass COMMENT
  3004. #token "\*/"            << zzmode(START); zzskip(); >>
  3005. #token "~[\*]*"         << zzskip(); >>
  3006. #token "\*~[/]"         << zzskip(); >>
  3007.  
  3008. /*
  3009.  * C++-style comment handling
  3010.  */
  3011. #lexclass CPPCOMMENT
  3012. #token "[\n\r]"         << zzmode(START); zzskip(); >>
  3013. #token "~[\n\r]"        << zzskip(); >>
  3014.  
  3015. #lexclass START
  3016.  
  3017. /*
  3018.  * Assorted literals
  3019.  */
  3020. #token OCT_NUM "0[0-7]*"
  3021. #token L_OCT_NUM "0[0-7]*[Ll]"
  3022. #token INT_NUM "[1-9][0-9]*"
  3023. #token L_INT_NUM "[1-9][0-9]*[Ll]"
  3024. #token HEX_NUM "0[Xx][0-9A-Fa-f]+"
  3025. #token L_HEX_NUM "0[Xx][0-9A-Fa-f]+[Ll]"
  3026. #token FLOAT_NUM "([1-9][0-9]*{.[0-9]*} | {0}.[0-9]+) {[Ee]{[\+\-]}[0-9]+}"
  3027.  
  3028. /*
  3029.  * Identifiers
  3030.  */
  3031. #token Identifier "[_a-zA-Z][_a-zA-Z0-9]*"
  3032.  
  3033.                                                                        Page 62
  3034. ===============================================================================
  3035. Example 2: ASTs
  3036. ===============================================================================
  3037. #header <<
  3038.  
  3039. #include "charbuf.h"
  3040. #include <string.h>
  3041.  
  3042. int nextSerial;
  3043.  
  3044. #define AST_FIELDS int token; int serial; char *text;
  3045. #include "ast.h"
  3046.  
  3047. #define zzcr_ast(ast,attr,tok,astText) \
  3048.    (ast)->token=tok; \
  3049.    (ast)->text=strdup( (char *)  &(  (  (attr)->text  )  )  ); \
  3050.    nextSerial++; \
  3051.    (ast)->serial=nextSerial; \
  3052.  
  3053. #define zzd_ast(node) delete_ast(node)
  3054.  
  3055. void delete_ast (AST *node);
  3056.  
  3057. >>
  3058.  
  3059. <<
  3060.  
  3061. AST     *root=NULL;
  3062.  
  3063. void show(AST *tree) {
  3064.         if (tree->token==ID) {
  3065.           printf (" %s <#%d> ",
  3066.                 tree->text,tree->serial);}
  3067.         else {
  3068.           printf (" %s <#%d> ",
  3069.                 zztokens[tree->token],
  3070.                 tree->serial);
  3071.         };
  3072. }
  3073. void before (AST *tree) {
  3074.         printf ("(");
  3075. }
  3076. void after (AST *tree) {
  3077.         printf (")");
  3078. }
  3079.  
  3080.  
  3081. void delete_ast(AST *node) {
  3082.   printf ("\nzzd_ast called for <node #%d>\n",node->serial);
  3083.   free (node->text);
  3084.   return;
  3085. }
  3086.  
  3087.                                                                        Page 63
  3088. int main() {
  3089.         nextSerial=0;
  3090.         ANTLR (expr(&root),stdin);
  3091.         printf ("\n");
  3092.         zzpre_ast(root,show,before,after);
  3093.         printf ("\n");
  3094.         zzfree_ast(root);
  3095.         return 0;
  3096. }
  3097. >>
  3098.  
  3099. #token  WhiteSpace      "[\ \t]"                <<zzskip();>>
  3100. #token  ID              "[a-z A-Z]*"
  3101. #token  NEWLINE         "\n"
  3102. #token  OpenAngle       "<"
  3103. #token  CloseAngle      ">"
  3104.  
  3105. expr    : (expr0 NEWLINE)
  3106.  
  3107. ;expr0  : expr1 {"="^ expr0}
  3108. ;expr1  : expr2 ("\+"^ expr2)*
  3109. ;expr2  : expr3 ("\*"^ expr3)*
  3110. ;expr3  : ID
  3111. -------------------------------------------------------------------------------
  3112. Sample output from this program:
  3113.  
  3114. a=b=c=d
  3115. ( = <#2>  a <#1> ( = <#4>  b <#3> ( = <#6>  c <#5>  d <#7> ))) NEWLINE <#8>
  3116. zzd_ast called for <node #7>
  3117. zzd_ast called for <node #5>
  3118. zzd_ast called for <node #6>
  3119. zzd_ast called for <node #3>
  3120. zzd_ast called for <node #4>
  3121. zzd_ast called for <node #1>
  3122. zzd_ast called for <node #8>
  3123. zzd_ast called for <node #2>
  3124.  
  3125. a+b*c
  3126. ( \+ <#2>  a <#1> ( \* <#4>  b <#3>  c <#5> )) NEWLINE <#6>
  3127. zzd_ast called for <node #5>
  3128. zzd_ast called for <node #3>
  3129. zzd_ast called for <node #4>
  3130. zzd_ast called for <node #1>
  3131. zzd_ast called for <node #6>
  3132. zzd_ast called for <node #2>
  3133.  
  3134. a*b+c
  3135. ( \+ <#4> ( \* <#2>  a <#1>  b <#3> ) c <#5> ) NEWLINE <#6>
  3136. zzd_ast called for <node #3>
  3137. zzd_ast called for <node #1>
  3138. zzd_ast called for <node #5>
  3139. zzd_ast called for <node #2>
  3140. zzd_ast called for <node #6>
  3141. zzd_ast called for <node #4>
  3142.  
  3143.                                                                        Page 64
  3144. ===============================================================================
  3145. Example 3: Syntactic Predicates
  3146. ===============================================================================
  3147. Not completed.
  3148. ===============================================================================
  3149. Example 4: DLG input function
  3150. ===============================================================================
  3151. This example demonstrates the use of a DLG input function to work
  3152. around a limitation of DLG.  In this example the user wants to
  3153. recognize an exclamation mark as the first character of a line and
  3154. treat it differently from an exclamation mark elsewhere.  The
  3155. workaround is for the input function to return a non-printing
  3156. character (binary 1) when it finds an "!" in column 1.  If it reads a
  3157. genuine binary 1 in column 1 of the input text it returns a "?".
  3158.  
  3159. The parse is started by:
  3160.  
  3161.         int DLGchar (void);
  3162.         ...
  3163.         ANTLRf (expr(&root),DLGchar);
  3164.         ...
  3165. -------------------------------------------------------------------------------
  3166. #token  BANG            "!"
  3167. #token  BANG_COL1       "\01"
  3168. #token  WhiteSpace      "[\ \t]"        <<zzskip();>>
  3169. #token  ID              "[a-z A-Z]*"
  3170. #token  NEWLINE         "\n"
  3171.  
  3172. expr!   : (bang         <<printf ("\nThe ! is NOT in column 1\n");>>
  3173.            | bang1      <<printf ("\nThe ! is in column 1\n");>>
  3174.            | id         <<printf ("\nFirst token is an ID\n");>>
  3175.           )* "@"
  3176.  
  3177. ;bang!  : BANG ID NEWLINE
  3178.  
  3179. ;bang1! : BANG_COL1 ID  NEWLINE
  3180.  
  3181. ;id!    : ID  NEWLINE
  3182. ;
  3183. -------------------------------------------------------------------------------
  3184.  
  3185.                                                                        Page 65
  3186. #include <stdio.h>
  3187.  
  3188. /*
  3189.         Antlr DLG input function - See page 18 of pccts 1.00 manual
  3190. */
  3191.  
  3192. static int firstTime=1;
  3193.  
  3194. static int c;
  3195.  
  3196. int DLGchar (void) {
  3197.     if (feof(stdin)) {
  3198.         return EOF;
  3199.     };
  3200.     if (firstTime || c=='\n') {
  3201.       firstTime=0;
  3202.       c=fgetc(stdin);
  3203.       if (c==EOF) return (EOF);
  3204.       if (c=='!') return ('\001');
  3205.       if (c=='\001') return ('?');
  3206.       return (c);
  3207.     } else {
  3208.       c=fgetc(stdin);
  3209.       return (c);
  3210.     };
  3211. };
  3212.  
  3213.                                                                        Page 66
  3214. ===============================================================================
  3215. Example 5: Maintaining a Stack of DLG Modes
  3216. ===============================================================================
  3217. Contributed by David Seidel
  3218.  
  3219. When placed in a #lexaction or a separate file then the modifier "static"
  3220. must be dropped from the declaration of zzauto (line 61) in "dlgauto.h".
  3221.  
  3222. These routines have now been incorporated in pccts version 1.30b4. They
  3223. are defined in pccts/h/err.h and are guarded by #ifdef USER_ZZMODE_STACK.
  3224.  
  3225. This example will be dropped if they are still part of 1.31 upon its official
  3226. release.
  3227. -------------------------------------------------------------------------------
  3228. #define  MAX_MODE ???
  3229. #define  ZZMAXSTK (MAX_MODE * 2)
  3230.  
  3231. static int  zzmstk[ZZMAXSTK] = { -1 };
  3232. static int  zzmdep = 0;
  3233. static char msgArea[100];
  3234.  
  3235. void
  3236. #ifdef __STDC__
  3237. zzmpush( int m )
  3238. #else
  3239. zzmpush( m )
  3240. int m;
  3241. #endif
  3242. {
  3243.    if(zzmdep == ZZMAXSTK - 1)
  3244.    {  sprintf(msgArea, "Mode stack overflow ");
  3245.       zzerr(msgArea);
  3246.    }
  3247.    else
  3248.    {  zzmstk[zzmdep++] = zzauto;
  3249.       zzmode(m);
  3250.    }
  3251. }
  3252.  
  3253. void
  3254. zzmpop()
  3255. {
  3256.    if(zzmdep == 0)
  3257.    {  sprintf(msgArea, "Mode stack underflow ");
  3258.       zzerr(msgArea);
  3259.    }
  3260.    else
  3261.    {  zzmdep--;
  3262.       zzmode(zzmstk[zzmdep]);
  3263.    }
  3264. }
  3265.  
  3266.                                                                        Page 67
  3267. -------------------------------------------------------------------------------
  3268. A modified version of the above routine which allows the user to pass a
  3269. a routine to be executed when the mode is popped from the stack.
  3270.  
  3271. When placed in a #lexaction or a separate file then the modifier "static"
  3272. must be dropped from the declaration of zzauto (line 61) in "dlgauto.h".
  3273. -------------------------------------------------------------------------------
  3274. #define ZZMAXSTK ????
  3275.  
  3276. static int  zzmstk[ZZMAXSTK] = { -1 };  /* stack of DLG modes */
  3277. static void (*zzfuncstk[ZZMAXSTK])();   /* stack of pointer to functions */
  3278. static int  zzmdep = 0;
  3279. static char msgArea[100];
  3280.  
  3281. void pushMode( int m ,void (*func)())
  3282. {
  3283.    if(zzmdep == ZZMAXSTK - 1)
  3284.    {  sprintf(msgArea, "Mode stack overflow ");
  3285.       zzerr(msgArea);
  3286.    }
  3287.    else
  3288.    {  zzmstk[zzmdep] = zzauto;
  3289.       zzfuncstk[zzmdep] = func;
  3290.       zzmdep++;
  3291.       zzmode(m);
  3292.    }
  3293. }
  3294.  
  3295. void popMode()
  3296. {
  3297.    void (*thisFunc)();
  3298.    if(zzmdep == 0)
  3299.    {  sprintf(msgArea, "Mode stack underflow ");
  3300.       zzerr(msgArea);
  3301.    }
  3302.    else
  3303.    {  zzmdep--;
  3304.       thisFunc=zzfuncstk[zzmdep];
  3305.       zzmode(zzmstk[zzmdep]);
  3306.       zzmstk[zzmdep]=0;
  3307.       zzfuncstk[zzmdep]=0;
  3308.         /* this call might result in indirect recursion of popMode() */
  3309.       if (thisFunc!=0) {
  3310.         (*thisFunc)();
  3311.       };
  3312.    }
  3313. }
  3314.  
  3315. void resetModeStack() {
  3316.    zzmdep=0;
  3317.    zzmstk[0]=0;
  3318.    zzfuncstk[0]=0;
  3319. }
  3320.  
  3321. /*  if the lookahead character is a semi-colon then keep on popping */
  3322.  
  3323. void popOnSC() {
  3324.    if (zzchar==';') popMode();
  3325. }
  3326.  
  3327.                                                                        Page 68
  3328. ===============================================================================
  3329. Example 6: Debug code for create_ast, mk_ast, delete_ast to locate lost ASTs
  3330. ===============================================================================
  3331. This is an example of code which tries to keep track of lost ASTs using
  3332. a doubly linked list of all ASTs maintained by calls from create_ast()
  3333. and mk_ast() to zzastnew_userhook().  When ASTs are deleted by calls
  3334. to zzastdelete_userhook() from the user's AST delete routines they are
  3335. removed from the doubly linked list.  Any ASTs left over after zzfree_ast()
  3336. must be considered lost.
  3337.  
  3338. This method does not monitor ASTs created by zzdup_ast() because it does
  3339. not call the create_ast() or mk_ast() routines.
  3340. -------------------------------------------------------------------------------
  3341. The #header section must include a definition of AST_FIELDS with the
  3342. equivalent of:
  3343.  
  3344.         struct _ast *flink, *blink;
  3345. -------------------------------------------------------------------------------
  3346. int main() {
  3347.     ...
  3348. again:
  3349.     ...
  3350.     reset_ASTlistHead();        /*  <======================== */
  3351.     ANTLR (sourcecode(&root),stdin);
  3352.     treewalk(root);
  3353.     zzfree_ast(root);
  3354.     root=NULL;
  3355.     print_lost_ast();           /*   <======================= */
  3356.     printf ("\n");}
  3357.     ...
  3358.     goto again;
  3359.     ...
  3360. }
  3361. -------------------------------------------------------------------------------
  3362. #ifndef H_ZZNEWAST_USERHOOK
  3363. #define H_ZZNEWAST_USERHOOK
  3364.  
  3365. void reset_ASTlistHead(void);
  3366. void zzunhook_tree(void);
  3367. void zzastnew_userhook(AST *newNode);
  3368. void zzastdelete_userhook (AST *singleNode);
  3369. void print_lost_ast (void);
  3370. void treewalk(AST *tree);
  3371.  
  3372. #endif
  3373. -------------------------------------------------------------------------------
  3374. #include "stdpccts.h"
  3375. #include "stdlib.h"
  3376. #include "zzastnew_userhook.h"
  3377.  
  3378. static AST ASTlistHead;
  3379. static int ASTserialNumber;
  3380.  
  3381. void reset_ASTlistHead(void) {
  3382.   while (ASTlistHead.flink!=0 && ASTlistHead.flink!= &ASTlistHead) {
  3383.          zzfree_ast(ASTlistHead.flink);
  3384.   };
  3385.   ASTlistHead.flink=&ASTlistHead;
  3386.   ASTlistHead.blink=&ASTlistHead;
  3387.   ASTserialNumber=1;
  3388.   return;
  3389. }
  3390.  
  3391.                                                                        Page 69
  3392. /*  Stop tracking ASTs in a tree without actually deleting them */
  3393.  
  3394. void zzunhook_tree (AST * tree) {
  3395.  
  3396.         while (tree != 0) {
  3397.           zzunhook_tree (tree->down);
  3398.           zzastdelete_userhook (tree);
  3399.           tree=tree->right;
  3400.         };
  3401.         return;
  3402. }
  3403.  
  3404. /*  Track new AST */
  3405.  
  3406. void zzastnew_userhook(AST *newNode) {
  3407.  
  3408.         AST  *prev;
  3409.  
  3410.         prev=ASTlistHead.blink;
  3411.         prev->flink=newNode;
  3412.         ASTlistHead.blink=newNode;
  3413.         newNode->blink=prev;
  3414.         newNode->flink=&ASTlistHead;
  3415.         newNode->serialNumber=ASTserialNumber;
  3416.         ASTserialNumber++;
  3417.         return;
  3418. }
  3419.  
  3420. /*  Stop tracking an AST */
  3421.  
  3422. void zzastdelete_userhook (AST *singleNode) {
  3423.  
  3424.         AST *fnode;
  3425.         AST *bnode;
  3426.  
  3427.         if (singleNode!=0) {
  3428.                 fnode=singleNode->flink;
  3429.                 bnode=singleNode->blink;
  3430.                 fnode->blink=bnode;
  3431.                 bnode->flink=fnode;
  3432.                 singleNode->serialNumber=0;
  3433.                 singleNode->flink=0;
  3434.                 singleNode->blink=0;
  3435.         };
  3436.         return;
  3437. }
  3438.  
  3439. /*  Print ASTs that are still on list */
  3440.  
  3441. void print_lost_ast () {
  3442.  
  3443.   AST *node;
  3444.  
  3445.   for (node=ASTlistHead.flink;
  3446.        node!=0 && node!= &ASTlistHead;
  3447.        node=node->flink) {
  3448.          printf ("**** Start of lost AST listing **** %d\n",node->serialNumber);
  3449.          treewalk (node);               /*  user supplied routine */
  3450.          printf ("\n**** End of lost AST listing ****\n");
  3451.        };
  3452. }
  3453.  
  3454.                                                                        Page 70
  3455. -------------------------------------------------------------------------------
  3456. These routines print out the AST tree.  This will be application dependent.
  3457. -------------------------------------------------------------------------------
  3458. #include "stdpccts.h"
  3459. #include "stdlib.h"
  3460.  
  3461. static int treenest=0;
  3462.  
  3463. void  treeindent(int nesting) {
  3464.   int i;
  3465.   for (i=0;i<nesting*2;i++) {
  3466.     printf (" ");
  3467.   };
  3468.   return;
  3469. }
  3470.  
  3471. void treewalk1 (AST *tree) {
  3472.         while (tree != NULL) {
  3473.                 treeindent(treenest);
  3474.                 printf ("%s",zztokens[tree->token]);
  3475.                 if (tree->text != NULL) {
  3476.                   printf ("  %s",tree->text);
  3477.                 };
  3478.                 printf ("\n");
  3479.                 treenest++;
  3480.                 treewalk1 (tree->down);
  3481.                 treenest--;
  3482.                 tree=tree->right;
  3483.         };
  3484.         return;
  3485. }
  3486.  
  3487. void treewalk (AST *tree) {
  3488.   treenest=0;
  3489.   treewalk1(tree);
  3490.   return;
  3491. }
  3492.  
  3493.                                                                        Page 71
  3494. ===============================================================================
  3495. Example 7: Difference Between Various Types of Lookahead in Antlr/DLG
  3496. ===============================================================================
  3497. The following grammar with k=1 and standard lookahead is meant to show how
  3498. zzlextext and LATEXT(i) differ for the case k=1 and k=3 (see later
  3499. examples).
  3500.  
  3501. The use of LA(1) and LATEXT(1) in semantic predicates is OK, but their use
  3502. in actions is NOT recommended because, as the examples below show, there is
  3503. a variation in what LATEXT(1) means when it appears in an action.
  3504.  
  3505. Use attributes to refer to tokens already encountered.
  3506. -------------------------------------------------------------------------------
  3507. #header <<
  3508.  
  3509. #include "charbuf.h"
  3510.  
  3511. #define ZZCOL
  3512.  
  3513. >>
  3514.  
  3515. <<
  3516.  
  3517. /*  Can't put quoted strings in semantic predicates in version 1.23 */
  3518.  
  3519. #define Semantic_Predicate_Of_1 "Semantic Predicate Of 1"
  3520.  
  3521. int     AntlrCount=0;
  3522.  
  3523. int main() {
  3524. again:  ANTLR (statement(),stdin);
  3525.         return 0;
  3526. }
  3527.  
  3528. #define LANL(i) (*LATEXT(i) == '\n' ? "NL" : LATEXT(i))
  3529. #define LAINFNL(i) (*ZZINF_LATEXT(i) == '\n' ? "NL" : ZZINF_LATEXT(i))
  3530.  
  3531. void laDump(char * label) {
  3532.   AntlrCount++;
  3533.   printf ("\tRecognized: %s (AntlrCount=%d)\n",label,AntlrCount);
  3534.   printf ("\tValue of zzbegcol: %d\n",zzbegcol);
  3535.   printf ("\tLATEXT(0..1)={%s,%s}\n",
  3536.                 LANL(0),LANL(1));
  3537.   printf ("\tzzlextext=%s\n",(zzlextext[0]=='\n' ? "NL" : zzlextext) );
  3538. #ifdef ZZINF_LOOK
  3539.   printf ("\tZZINF_LATEXT(0..1)={%s,%s}\n",
  3540.                 LAINFNL(0),LAINFNL(1));
  3541. #endif
  3542.   return;
  3543. }
  3544.  
  3545. >>
  3546.  
  3547. #lexaction <<
  3548.  
  3549. int     DLGcount=0;
  3550.  
  3551. >>
  3552.  
  3553.                                                                        Page 72
  3554. #token  ID      "[a-z]*"
  3555.         <<DLGcount++;printf("DLGcount: %d Col %d ID=(%s)\n",
  3556.           DLGcount,zzbegcol,zzlextext);>>
  3557. #token  WS      "[\ \t]*"
  3558.         <<DLGcount++;printf("DLGcount: %d Col %d WS\n",DLGcount,zzbegcol);zzskip();>>
  3559. #token  NL      "\n"
  3560.         <<DLGcount++;printf("DLGcount: %d Col %d NL\n",
  3561.           DLGcount,zzbegcol);
  3562.           zzendcol=0;
  3563.           zzline++;>>
  3564.  
  3565. statement : (formats) * "@"
  3566.  
  3567. ;formats
  3568.        : format1
  3569.        | format2
  3570.  
  3571. ;format1 :
  3572.         <<(laDump(Semantic_Predicate_Of_1),1)>>?
  3573.         ID
  3574.         <<laDump("After first ID of 1");>>
  3575.         ID
  3576.         <<laDump("After second ID of 1");>>
  3577.         ID
  3578.         <<laDump("After third ID of 1");>>
  3579.         NL
  3580.         <<laDump("-> Format 1 After: ID ID ID NL");>>
  3581. ;format2 :
  3582.         ID ID ID;
  3583. -------------------------------------------------------------------------------
  3584. The input data file:
  3585. -------------------------------------------------------------------------------
  3586. a b c
  3587. d e f
  3588.  
  3589.                                                                        Page 73
  3590. -------------------------------------------------------------------------------
  3591. The output from the standard and the interactive parser were identical in
  3592. this case.
  3593. -------------------------------------------------------------------------------
  3594. DLGcount: 1 Col 1 ID=(a)
  3595.         Recognized: Semantic Predicate Of 1 (AntlrCount=1)
  3596.         Value of zzbegcol: 1
  3597.         LATEXT(0..1)={a,a}
  3598.         zzlextext=a
  3599.         Recognized: Semantic Predicate Of 1 (AntlrCount=2)
  3600.         Value of zzbegcol: 1
  3601.         LATEXT(0..1)={a,a}
  3602.         zzlextext=a
  3603.         Recognized: Semantic Predicate Of 1 (AntlrCount=3)
  3604.         Value of zzbegcol: 1
  3605.         LATEXT(0..1)={a,a}
  3606.         zzlextext=a
  3607.         Recognized: After first ID of 1 (AntlrCount=4)
  3608.         Value of zzbegcol: 1
  3609.         LATEXT(0..1)={a,a}
  3610.         zzlextext=a
  3611. DLGcount: 2 Col 2 WS
  3612. DLGcount: 3 Col 3 ID=(b)
  3613.         Recognized: After second ID of 1 (AntlrCount=5)
  3614.         Value of zzbegcol: 3
  3615.         LATEXT(0..1)={b,b}
  3616.         zzlextext=b
  3617. DLGcount: 4 Col 4 WS
  3618. DLGcount: 5 Col 5 ID=(c)
  3619.         Recognized: After third ID of 1 (AntlrCount=6)
  3620.         Value of zzbegcol: 5
  3621.         LATEXT(0..1)={c,c}
  3622.         zzlextext=c
  3623. DLGcount: 6 Col 6 NL
  3624.         Recognized: -> Format 1 After: ID ID ID NL (AntlrCount=7)
  3625.         Value of zzbegcol: 6
  3626.         LATEXT(0..1)={NL,NL}
  3627.         zzlextext=NL
  3628. DLGcount: 7 Col 1 ID=(d)
  3629.         Recognized: Semantic Predicate Of 1 (AntlrCount=8)
  3630.         Value of zzbegcol: 1
  3631.         LATEXT(0..1)={d,d}
  3632.         zzlextext=d
  3633.         Recognized: Semantic Predicate Of 1 (AntlrCount=9)
  3634.         Value of zzbegcol: 1
  3635.         LATEXT(0..1)={d,d}
  3636.         zzlextext=d
  3637.         Recognized: Semantic Predicate Of 1 (AntlrCount=10)
  3638.         Value of zzbegcol: 1
  3639.         LATEXT(0..1)={d,d}
  3640.         zzlextext=d
  3641.         Recognized: After first ID of 1 (AntlrCount=11)
  3642.         Value of zzbegcol: 1
  3643.         LATEXT(0..1)={d,d}
  3644.         zzlextext=d
  3645.         DLGcount: 8 Col 2 WS
  3646. <remaining output omitted>
  3647.  
  3648.                                                                        Page 74
  3649. -------------------------------------------------------------------------------
  3650. The same grammar and input file when compiled with -DZZINF_LOOK
  3651. -------------------------------------------------------------------------------
  3652. DLGcount: 1 Col 1 ID=(a)
  3653. DLGcount: 2 Col 2 WS
  3654. DLGcount: 3 Col 3 ID=(b)
  3655. DLGcount: 4 Col 4 WS
  3656. DLGcount: 5 Col 5 ID=(c)
  3657. DLGcount: 6 Col 6 NL
  3658. DLGcount: 7 Col 1 ID=(d)
  3659. DLGcount: 8 Col 2 WS
  3660. DLGcount: 9 Col 3 ID=(e)
  3661. DLGcount: 10 Col 4 WS
  3662. DLGcount: 11 Col 5 ID=(f)
  3663. DLGcount: 12 Col 6 NL
  3664.         Recognized: Semantic Predicate Of 1 (AntlrCount=1)
  3665.         Value of zzbegcol: 1
  3666.         LATEXT(0..1)={a,a}
  3667.         zzlextext=a
  3668.         ZZINF_LATEXT(0..1)={a,b}
  3669.         Recognized: Semantic Predicate Of 1 (AntlrCount=2)
  3670.         Value of zzbegcol: 1
  3671.         LATEXT(0..1)={a,a}
  3672.         zzlextext=a
  3673.         ZZINF_LATEXT(0..1)={a,b}
  3674.         Recognized: Semantic Predicate Of 1 (AntlrCount=3)
  3675.         Value of zzbegcol: 1
  3676.         LATEXT(0..1)={a,a}
  3677.         zzlextext=a
  3678.         ZZINF_LATEXT(0..1)={a,b}
  3679.         Recognized: After first ID of 1 (AntlrCount=4)
  3680.         Value of zzbegcol: 1
  3681.         LATEXT(0..1)={a,a}
  3682.         zzlextext=a
  3683.         ZZINF_LATEXT(0..1)={a,b}
  3684.         Recognized: After second ID of 1 (AntlrCount=5)
  3685.         Value of zzbegcol: 1
  3686.         LATEXT(0..1)={b,b}
  3687.         zzlextext=b
  3688.         ZZINF_LATEXT(0..1)={b,c}
  3689.         Recognized: After third ID of 1 (AntlrCount=6)
  3690.         Value of zzbegcol: 1
  3691.         LATEXT(0..1)={c,c}
  3692.         zzlextext=c
  3693.         ZZINF_LATEXT(0..1)={c,NL}
  3694.         Recognized: -> Format 1 After: ID ID ID NL (AntlrCount=7)
  3695.         Value of zzbegcol: 1
  3696.         LATEXT(0..1)={NL,NL}
  3697.         zzlextext=NL
  3698.         ZZINF_LATEXT(0..1)={NL,d}
  3699.         Recognized: Semantic Predicate Of 1 (AntlrCount=8)
  3700.         Value of zzbegcol: 1
  3701.         LATEXT(0..1)={d,d}
  3702.         zzlextext=d
  3703.         ZZINF_LATEXT(0..1)={d,e}
  3704. <remaining output omitted>
  3705.  
  3706.                                                                        Page 75
  3707. -------------------------------------------------------------------------------
  3708. The following grammar with k=3 is meant to show aspects of lookahead choices.
  3709. -------------------------------------------------------------------------------
  3710. #header <<
  3711.  
  3712. #include "charbuf.h"
  3713.  
  3714. #define ZZCOL
  3715.  
  3716. >>
  3717.  
  3718. <<
  3719.  
  3720. /*  Can't put quoted strings in semantic predicates in version 1.23 */
  3721.  
  3722. #define Semantic_Predicate_Of_1 "Semantic Predicate Of 1"
  3723.  
  3724. int     AntlrCount=0;
  3725.  
  3726. int main() {
  3727. again:  ANTLR (statement(),stdin);
  3728.         return 0;
  3729. }
  3730.  
  3731. #define LANL(i) (*LATEXT(i) == '\n' ? "NL" : LATEXT(i))
  3732. #define LAINFNL(i) (*ZZINF_LATEXT(i) == '\n' ? "NL" : ZZINF_LATEXT(i))
  3733.  
  3734. void laDump(char * label) {
  3735.   AntlrCount++;
  3736.   printf ("\tRecognized: %s (AntlrCount=%d)\n",label,AntlrCount);
  3737.   printf ("\tValue of zzbegcol: %d\n",zzbegcol);
  3738.   printf ("\tLATEXT(0..3)={%s,%s,%s,%s}\n",
  3739.                 LANL(0),LANL(1),LANL(2),LANL(3));
  3740.   printf ("\tzzlextext=%s\n",(zzlextext[0]=='\n' ? "NL" : zzlextext) );
  3741. #ifdef ZZINF_LOOK
  3742.   printf ("\tZZINF_LATEXT(0..3)={%s,%s,%s,%s}\n",
  3743.                 LAINFNL(0),LAINFNL(1),LAINFNL(2),LAINFNL(3));
  3744. #endif
  3745.   return;
  3746. }
  3747.  
  3748. >>
  3749.  
  3750. #lexaction <<
  3751.  
  3752. int     DLGcount=0;
  3753.  
  3754. >>
  3755.  
  3756. #token  ID      "[a-z]*"
  3757.         <<DLGcount++;printf("DLGcount: %d Col %d ID=(%s)\n",
  3758.           DLGcount,zzbegcol,zzlextext);>>
  3759. #token  WS      "[\ \t]*"
  3760.         <<DLGcount++;printf("DLGcount: %d Col %d WS\n",DLGcount,zzbegcol);zzskip();>>
  3761. #token  NL      "\n"
  3762.         <<DLGcount++;printf("DLGcount: %d Col %d NL\n",
  3763.           DLGcount,zzbegcol);
  3764.           zzendcol=0;
  3765.           zzline++;>>
  3766.  
  3767.                                                                        Page 76
  3768. statement : (formats) * "@"
  3769.  
  3770. ;formats
  3771.        : format1
  3772.        | format2
  3773.  
  3774. ;format1 :
  3775.         <<(laDump(Semantic_Predicate_Of_1),1)>>?
  3776.         ID
  3777.         <<laDump("After first ID of 1");>>
  3778.         ID
  3779.         <<laDump("After second ID of 1");>>
  3780.         ID
  3781.         <<laDump("After third ID of 1");>>
  3782.         NL
  3783.         <<laDump("-> Format 1 After: ID ID ID NL");>>
  3784. ;format2 :
  3785.         ID ID ID NL     <<laDump("-> Format 2: ID ID ID");>>
  3786. ;
  3787. -------------------------------------------------------------------------------
  3788. The input data file:
  3789. -------------------------------------------------------------------------------
  3790. a b c
  3791. d e f
  3792.  
  3793.                                                                        Page 77
  3794. -------------------------------------------------------------------------------
  3795. When built with version 1.23 and "standard" options: AFLAGS = -k 3
  3796. -------------------------------------------------------------------------------
  3797. DLGcount: 1 Col 1 ID=(a)
  3798. DLGcount: 2 Col 2 WS
  3799. DLGcount: 3 Col 3 ID=(b)
  3800. DLGcount: 4 Col 4 WS
  3801. DLGcount: 5 Col 5 ID=(c)
  3802. DLGcount: 6 Col 6 NL
  3803.         Recognized: Semantic Predicate Of 1 (AntlrCount=1)
  3804.         Value of zzbegcol: 6
  3805.         LATEXT(0..3)={NL,a,b,c}
  3806.         zzlextext=a
  3807.         Recognized: Semantic Predicate Of 1 (AntlrCount=2)
  3808.         Value of zzbegcol: 6
  3809.         LATEXT(0..3)={NL,a,b,c}
  3810.         zzlextext=a
  3811.         Recognized: Semantic Predicate Of 1 (AntlrCount=3)
  3812.         Value of zzbegcol: 6
  3813.         LATEXT(0..3)={NL,a,b,c}
  3814.         zzlextext=a
  3815.         Recognized: After first ID of 1 (AntlrCount=4)
  3816.         Value of zzbegcol: 6
  3817.         LATEXT(0..3)={NL,a,b,c}
  3818.         zzlextext=a
  3819. DLGcount: 7 Col 1 ID=(d)
  3820.         Recognized: After second ID of 1 (AntlrCount=5)
  3821.         Value of zzbegcol: 1
  3822.         LATEXT(0..3)={d,b,c,NL}
  3823.         zzlextext=b
  3824. DLGcount: 8 Col 2 WS
  3825. DLGcount: 9 Col 3 ID=(e)
  3826.         Recognized: After third ID of 1 (AntlrCount=6)
  3827.         Value of zzbegcol: 3
  3828.         LATEXT(0..3)={e,c,NL,d}
  3829.         zzlextext=c
  3830. DLGcount: 10 Col 4 WS
  3831. DLGcount: 11 Col 5 ID=(f)
  3832.         Recognized: -> Format 1 After: ID ID ID NL (AntlrCount=7)
  3833.         Value of zzbegcol: 5
  3834.         LATEXT(0..3)={f,NL,d,e}
  3835.         zzlextext=NL
  3836. DLGcount: 12 Col 6 NL
  3837.         Recognized: Semantic Predicate Of 1 (AntlrCount=8)
  3838.         Value of zzbegcol: 6
  3839.         LATEXT(0..3)={NL,d,e,f}
  3840.         zzlextext=d
  3841.         Recognized: Semantic Predicate Of 1 (AntlrCount=9)
  3842.         Value of zzbegcol: 6
  3843.         LATEXT(0..3)={NL,d,e,f}
  3844.         zzlextext=d
  3845.         Recognized: Semantic Predicate Of 1 (AntlrCount=10)
  3846.         Value of zzbegcol: 6
  3847.         LATEXT(0..3)={NL,d,e,f}
  3848.         zzlextext=d
  3849.         Recognized: After first ID of 1 (AntlrCount=11)
  3850.         Value of zzbegcol: 6
  3851.         LATEXT(0..3)={NL,d,e,f}
  3852.         zzlextext=d
  3853. <remaining output omitted>
  3854.  
  3855.                                                                        Page 78
  3856. -------------------------------------------------------------------------------
  3857. When built with version 1.23 and "interactive" options: AFLAGS = -k 3 -gk
  3858. -------------------------------------------------------------------------------
  3859. DLGcount: 1 Col 1 ID=(a)
  3860.         Recognized: Semantic Predicate Of 1 (AntlrCount=1)
  3861.         Value of zzbegcol: 1
  3862.         LATEXT(0..3)={,a,,}
  3863.         zzlextext=
  3864. DLGcount: 2 Col 2 WS
  3865. DLGcount: 3 Col 3 ID=(b)
  3866. DLGcount: 4 Col 4 WS
  3867. DLGcount: 5 Col 5 ID=(c)
  3868.         Recognized: Semantic Predicate Of 1 (AntlrCount=2)
  3869.         Value of zzbegcol: 5
  3870.         LATEXT(0..3)={,a,b,c}
  3871.         zzlextext=
  3872.         Recognized: Semantic Predicate Of 1 (AntlrCount=3)
  3873.         Value of zzbegcol: 5
  3874.         LATEXT(0..3)={,a,b,c}
  3875.         zzlextext=
  3876.         Recognized: After first ID of 1 (AntlrCount=4)
  3877.         Value of zzbegcol: 5
  3878.         LATEXT(0..3)={a,b,c,}
  3879.         zzlextext=
  3880.         Recognized: After second ID of 1 (AntlrCount=5)
  3881.         Value of zzbegcol: 5
  3882.         LATEXT(0..3)={b,c,,a}
  3883.         zzlextext=
  3884.         Recognized: After third ID of 1 (AntlrCount=6)
  3885.         Value of zzbegcol: 5
  3886.         LATEXT(0..3)={c,,a,b}
  3887.         zzlextext=
  3888. DLGcount: 6 Col 6 NL
  3889.         Recognized: -> Format 1 After: ID ID ID NL (AntlrCount=7)
  3890.         Value of zzbegcol: 6
  3891.         LATEXT(0..3)={NL,a,b,c}
  3892.         zzlextext=a
  3893. DLGcount: 7 Col 1 ID=(d)
  3894.         Recognized: Semantic Predicate Of 1 (AntlrCount=8)
  3895.         Value of zzbegcol: 1
  3896.         LATEXT(0..3)={NL,d,b,c}
  3897.         zzlextext=b
  3898. DLGcount: 8 Col 2 WS
  3899. DLGcount: 9 Col 3 ID=(e)
  3900. DLGcount: 10 Col 4 WS
  3901. DLGcount: 11 Col 5 ID=(f)
  3902.         Recognized: Semantic Predicate Of 1 (AntlrCount=9)
  3903.         Value of zzbegcol: 5
  3904.         LATEXT(0..3)={NL,d,e,f}
  3905.         zzlextext=NL
  3906.         Recognized: Semantic Predicate Of 1 (AntlrCount=10)
  3907.         Value of zzbegcol: 5
  3908.         LATEXT(0..3)={NL,d,e,f}
  3909.         zzlextext=NL
  3910.         Recognized: After first ID of 1 (AntlrCount=11)
  3911.         Value of zzbegcol: 5
  3912.         LATEXT(0..3)={d,e,f,NL}
  3913.         zzlextext=NL
  3914. <remaining output omitted>
  3915.  
  3916.                                                                        Page 79
  3917. -------------------------------------------------------------------------------
  3918. When built with version 1.23 and infinite lookahead options:
  3919.         AFLAGS = -k 3
  3920.         CFLAGS = -DZZINF_LOOK
  3921. -------------------------------------------------------------------------------
  3922. DLGcount: 1 Col 1 ID=(a)
  3923. DLGcount: 2 Col 2 WS
  3924. DLGcount: 3 Col 3 ID=(b)
  3925. DLGcount: 4 Col 4 WS
  3926. DLGcount: 5 Col 5 ID=(c)
  3927. DLGcount: 6 Col 6 NL
  3928. DLGcount: 7 Col 1 ID=(d)
  3929. DLGcount: 8 Col 2 WS
  3930. DLGcount: 9 Col 3 ID=(e)
  3931. DLGcount: 10 Col 4 WS
  3932. DLGcount: 11 Col 5 ID=(f)
  3933. DLGcount: 12 Col 6 NL
  3934.         Recognized: Semantic Predicate Of 1 (AntlrCount=1)
  3935.         Value of zzbegcol: 1
  3936.         LATEXT(0..3)={NL,a,b,c}
  3937.         zzlextext=a
  3938.         ZZINF_LATEXT(0..3)={a,b,c,NL}
  3939.         Recognized: Semantic Predicate Of 1 (AntlrCount=2)
  3940.         Value of zzbegcol: 1
  3941.         LATEXT(0..3)={NL,a,b,c}
  3942.         zzlextext=a
  3943.         ZZINF_LATEXT(0..3)={a,b,c,NL}
  3944.         Recognized: Semantic Predicate Of 1 (AntlrCount=3)
  3945.         Value of zzbegcol: 1
  3946.         LATEXT(0..3)={NL,a,b,c}
  3947.         zzlextext=a
  3948.         ZZINF_LATEXT(0..3)={a,b,c,NL}
  3949.         Recognized: After first ID of 1 (AntlrCount=4)
  3950.         Value of zzbegcol: 1
  3951.         LATEXT(0..3)={NL,a,b,c}
  3952.         zzlextext=a
  3953.         ZZINF_LATEXT(0..3)={a,b,c,NL}
  3954.         Recognized: After second ID of 1 (AntlrCount=5)
  3955.         Value of zzbegcol: 1
  3956.         LATEXT(0..3)={d,b,c,NL}
  3957.         zzlextext=b
  3958.         ZZINF_LATEXT(0..3)={b,c,NL,d}
  3959.         Recognized: After third ID of 1 (AntlrCount=6)
  3960.         Value of zzbegcol: 1
  3961.         LATEXT(0..3)={e,c,NL,d}
  3962.         zzlextext=c
  3963.         ZZINF_LATEXT(0..3)={c,NL,d,e}
  3964.         Recognized: -> Format 1 After: ID ID ID NL (AntlrCount=7)
  3965.         Value of zzbegcol: 1
  3966.         LATEXT(0..3)={f,NL,d,e}
  3967.         zzlextext=NL
  3968.         ZZINF_LATEXT(0..3)={NL,d,e,f}
  3969.         Recognized: Semantic Predicate Of 1 (AntlrCount=8)
  3970.         Value of zzbegcol: 1
  3971.         LATEXT(0..3)={NL,d,e,f}
  3972.         zzlextext=d
  3973.         ZZINF_LATEXT(0..3)={d,e,f,NL}
  3974. <remaining output omitted>
  3975.  
  3976.                                                                        Page 80
  3977. ===============================================================================
  3978. Example 8: Preserving whitespace during lexing
  3979. ===============================================================================
  3980. The following program passes whitespace through DLG to the parser by
  3981. combining the whitespace with the token which follows it.  It is up to the
  3982. user to determine how to handle the leading whitespace during attribute
  3983. and AST creation.
  3984.  
  3985. In this example whitespace ("#token WS") includes only the space character:
  3986. it does not include tab or newline.  Maintaining accurate column
  3987. information when using zzmore() requires some extra work (as mentioned
  3988. in a note in the section on lexical issues.
  3989.  
  3990. The routines in "charbuf.h" assume that tokens are no longer than
  3991. "D_TextSize" characters.  The value can be changed from its default value
  3992. of 30 by  "#define D_TextSize ..." in the #header prior to the #include of
  3993. "charbuf.h".
  3994.  
  3995. It was built with k=1.
  3996. -------------------------------------------------------------------------------
  3997. #header <<
  3998.  
  3999. #include "charbuf.h"
  4000.  
  4001. #define ZZCOL
  4002.  
  4003. >>
  4004.  
  4005. <<
  4006.  
  4007. int AntlrCount=0;
  4008.  
  4009. int main() {
  4010. again:  ANTLR (statement(),stdin);
  4011.         return 0;
  4012. }
  4013.  
  4014. static char xlateBuf[100];
  4015.  
  4016. char * xlate (char * s) {
  4017.   char * p=s;
  4018.   char * q=xlateBuf;
  4019.   if (*p == 0) {
  4020.     *q='@';q++;
  4021.   };
  4022.   while (*p != 0) {
  4023.     if (*p == ' ') {
  4024.         *q='-';q++;
  4025.     } else if (*p == '\t') {
  4026.         *q='\\';q++;*q='t';q++;
  4027.     } else if (*p == '\n') {
  4028.         *q='\\';q++;*q='n';q++;
  4029.     } else {
  4030.         *q=*p;q++;
  4031.     };
  4032.   p++;
  4033.   };
  4034.   *q=0;
  4035.   return (xlateBuf);
  4036. }
  4037.  
  4038.                                                                        Page 81
  4039. void laDump(char * label) {
  4040.   AntlrCount++;
  4041.   printf ("\tRecognized: %s (AntlrCount=%d)   ",label,AntlrCount);
  4042.   printf ("zzlextext=(%s)\n",xlate(zzlextext));
  4043.   return;
  4044. }
  4045.  
  4046. >>
  4047.  
  4048. #lexaction <<
  4049.  
  4050. int     DLGcount=0;
  4051.  
  4052. >>
  4053.  
  4054. #token  ID      "[a-z]*"
  4055.         <<DLGcount++;printf("DLGcount: %d Col %d ID=(%s)\n",
  4056.           DLGcount,zzbegcol,zzlextext);>>
  4057. #token  WS      "[\ ]*"
  4058.         <<DLGcount++;printf("DLGcount: %d Col %d WS\n",DLGcount,zzbegcol);
  4059.           zzmore();>>
  4060. #token  NL      "\n"
  4061.         <<DLGcount++;printf("DLGcount: %d Col %d NL\n",
  4062.           DLGcount,zzbegcol);
  4063.           zzendcol=0;
  4064.           zzline++;
  4065.         >>
  4066.  
  4067. statement : (line) * "@"
  4068.  
  4069. ;line     : (ID  <<laDump("ID");>> ) * NL
  4070.  
  4071. ;
  4072.  
  4073.                                                                        Page 82
  4074. ===============================================================================
  4075. Example 9: Passing column information through DLG using a kludge
  4076. ===============================================================================
  4077. The following demonstrates a kludge which allows one to pass column
  4078. information through DLG for for use with attributes (or ASTs) even when
  4079. using modes with lookahead with LL_K>1 or using infinite lookahead
  4080. mode.  This technique is probably not necessary with C++ mode.
  4081. -------------------------------------------------------------------------------
  4082. #header <<
  4083.  
  4084. #include "col_charbuf.h"
  4085.  
  4086. #define ZZCOL
  4087.  
  4088. #include "shiftr.h"
  4089.  
  4090. #define COL_BITS_PER_BYTE 6
  4091. #define COL_BITS_MASK     ( (1 << COL_BITS_PER_BYTE) - 1 )
  4092.  
  4093. >>
  4094.  
  4095. <<
  4096.  
  4097. int main() {
  4098. again:  ANTLR (statement(),stdin);
  4099.         return 0;
  4100. }
  4101.  
  4102. void create_attr (Attrib *a,int tok,char *t) {
  4103.   char *        p;
  4104.   char *        q;
  4105.   int           i=0;
  4106.  
  4107.   a->col=0;
  4108.  
  4109.   for (p=t;*p != '\001' && *p != 0;p++) {
  4110.     if (i < D_TextSize-1) {
  4111.        a->text[i]=*p;
  4112.        i++;
  4113.     };
  4114.   };
  4115.  
  4116.   a->text[i]=0;
  4117.  
  4118.   if (*p == '\001') {
  4119.     a->col=p[1] & COL_BITS_MASK +
  4120.                 ( (p[2] & COL_BITS_MASK) << COL_BITS_PER_BYTE );
  4121.   };
  4122.  
  4123.   printf ("create_attr:   Col %d text=(%s)\n",a->col,a->text);
  4124.   return;
  4125. }
  4126.  
  4127. >>
  4128.  
  4129.                                                                        Page 83
  4130. #lexaction <<
  4131.  
  4132. int     DLGcount=0;
  4133. char    encodedCol[5];
  4134.  
  4135. void record() {
  4136.   encodedCol[0]='\001';
  4137.   encodedCol[1]=zzbegcol & COL_BITS_MASK;
  4138.   encodedCol[2]=(zzbegcol SHIFTR COL_BITS_PER_BYTE) & COL_BITS_MASK;
  4139.   encodedCol[4]=0;
  4140. /***
  4141. ****  if (strlen(zzlextext) > ZZLEXBUFSIZE - sizeof(encodedCol) ) {...}
  4142. ***/
  4143.   strcat(zzlextext,encodedCol);
  4144.   return;
  4145. }
  4146. >>
  4147.  
  4148. #token  ID      "[a-z A-Z 0-9]*"
  4149.         <<DLGcount++;printf("DLGcount:    %d Col %d ID=(%s)\n",
  4150.           DLGcount,zzbegcol,zzlextext);record();>>
  4151. #token  WS      "[\ \t]*"
  4152.         <<DLGcount++;printf("DLGcount:    %d Col %d WS\n",
  4153.           DLGcount,zzbegcol);zzskip();>>
  4154. #token  NL      "\n"
  4155.         <<DLGcount++;printf("DLGcount:    %d Col %d NL\n",
  4156.           DLGcount,zzbegcol);
  4157.           zzendcol=0;
  4158.           zzline++;
  4159.           zzskip();>>
  4160.  
  4161. statement : (formats) * "@" ;
  4162. formats   : ( ID ) * NL ;
  4163. -------------------------------------------------------------------------------
  4164. File: col_charbuf.h
  4165. -------------------------------------------------------------------------------
  4166. #ifndef ZZCHARBUF_H
  4167. #define ZZCHARBUF_H
  4168.  
  4169. #include <string.h>
  4170.  
  4171. #ifndef D_TextSize
  4172. #define D_TextSize      30
  4173.  
  4174. #endif
  4175.  
  4176. typedef struct {
  4177.         char    text[D_TextSize];
  4178.         int     col;
  4179.         } Attrib;
  4180.  
  4181. void create_attr(Attrib *a,int tok,char *t);
  4182.  
  4183. #define zzcr_attr(a,tok,t) create_attr(a,tok,t)
  4184.  
  4185. #endif
  4186. -------------------------------------------------------------------------------
  4187. File: shiftr.h
  4188. -------------------------------------------------------------------------------
  4189. #ifndef SHIFTR
  4190. #define SHIFTR >>
  4191. #endif
  4192.  
  4193.                                                                        Page 84
  4194. ===============================================================================
  4195. Example 10:  Use of #lexclass
  4196. ===============================================================================
  4197. The user has a grammar in which an asterisk ("*") is normally used to indicate
  4198. multiplication.  However, if "*" is the first token appearing in a statement
  4199. then it indicates a comment. Comments are terminated by a newline. Statements
  4200. are separated by semi-colons (";").  How does one use #lexclass to separate
  4201. the different lexical analysis required for comments and arithmetic
  4202. statements ?
  4203.  
  4204. For this example the recognized tokens have been reduced to identifiers and "*".
  4205.  
  4206. This code requires many #token actions to have the statement:
  4207.  
  4208.                 foundToken=1;
  4209.  
  4210. If this is inconvenient the user can modify dlgauto.h as outlined in
  4211. "Section on ANTLR/DLG Internals" to call a user-supplied routine (defined
  4212. inside the #lexaction) just after each call to the #token action routine.
  4213. -------------------------------------------------------------------------------
  4214. #header <<
  4215.  
  4216. #include "charbuf.h"
  4217.  
  4218. >>
  4219.  
  4220. <<
  4221. int main() {
  4222. again:  ANTLR (program(),stdin);
  4223.         return 0;
  4224. }
  4225. >>
  4226.  
  4227. #lexaction <<
  4228.  
  4229. int     foundToken=0;
  4230.  
  4231. >>
  4232.  
  4233. #lexclass START
  4234.  
  4235. #token  ID      "[a-z A-Z]*"    <<foundToken=1;>>
  4236. #token  SC      ";"             <<foundToken=0;>>
  4237. #token  WS      "[\ \t]*"       <<zzskip();>>
  4238. #token  NL      "\n"            <<zzskip();>>
  4239. #token  STAR    "\*"            <<if (foundToken == 0) {
  4240.                                    zzmode(LC_COMMENT);
  4241.                                    zzmore();};
  4242.                                 >>
  4243. #lexclass LC_COMMENT
  4244. #token  COMMENT "~[\n]*"        <<foundToken=0;
  4245.                                   zzmode(START);
  4246.                                 >>
  4247. program : (statement) * "@"
  4248.  
  4249. ;statement
  4250.         : COMMENT               <<printf ("comment: %s\n",$1.text);>>
  4251.         | (ID | STAR ) * SC     <<printf ("semi-colon\n");>>
  4252. ;
  4253.  
  4254.                                                                        Page 85
  4255. ===============================================================================
  4256. Example 11:  Use of zzchar and #lexclass
  4257. ===============================================================================
  4258. Consider the problem of distinguishing floating point numbers from
  4259. range expressions such as those used in Pascal:
  4260.  
  4261.         range:  1..23
  4262.         range:  a..z
  4263.         float:  1.23
  4264.  
  4265. As a first effort one might try:
  4266.  
  4267. #token  ID      "[a-z]*"
  4268. #token  Int     "[0-9]*"
  4269. #token  Range   ".."
  4270. #token  Float   "[0-9]*.[0-9]*"
  4271.  
  4272. The problem is that "1..23" looks like the floating point number "1." with
  4273. an illegal "." at the end.  DLG always takes the longest matching string,
  4274. so "1." will always look more appetizing than "1".  What one needs to do
  4275. is to look at the character following "1." to see if it is another ".",
  4276. and if it is to assume that it is a range expression.  The flex lexer has
  4277. trailing context, but DLG doesn't - except for the single character in
  4278. zzchar.
  4279.  
  4280. A solution in DLG is to write the #token Float action routine to look
  4281. at what's been accepted and at zzchar in order to decide what to do:
  4282. ------------------------------------------------------------------------
  4283. #header <<#include "int.h">>
  4284.  
  4285. #token Range    ".."
  4286. #token Int      "[0-9]*"
  4287. #token Float    "[0-9]*.[0-9]*"
  4288.         <<if (*zzendexpr == '.' && /* might use more complex test */
  4289.               zzchar == '.') {
  4290.                 NLA=Int;
  4291.                 zzmode(LC_Range);
  4292.           };
  4293.         >>
  4294. #token WS       "\ "    <<zzskip();>>
  4295. #token NL       "\n"    <<zzskip();>>
  4296.  
  4297. #lexclass LC_Range
  4298.  
  4299. // consume second "." of range token ("..") and return to normal mode
  4300.  
  4301. #token Range    "."      <<zzmode(START);>>
  4302.  
  4303. << int main() {
  4304.         ANTLR (rule(),stdin);
  4305.         }
  4306. >>
  4307. rule: ( Range <<printf ("range\n");>>
  4308.       | Int   <<printf ("int\n");>>
  4309.       | Float <<printf ("float\n");>>
  4310.       )*
  4311.       ;
  4312.  
  4313.                                                                        Page 86
  4314. ===============================================================================
  4315. Example 12: Rewriting a grammar so it be handled by Antlr
  4316. ===============================================================================
  4317. The original grammar was in this form:
  4318.  
  4319.          command := SET var BECOMES expr
  4320.                  |  SET var BECOMES QUOTE QUOTE
  4321.                  |  SET var BECOMES QUOTE expr QUOTE
  4322.                  |  SET var BECOMES QUOTE command QUOTE
  4323.  
  4324.          expr    := QUOTE anyCharButQuote QUOTE
  4325.                  |  expr AddOp expr
  4326.                  |  expr MulOp expr
  4327.  
  4328. The repetition of "SET var BECOMES" for command would require k=4 to
  4329. get to the interesting part.  The first step is to left-factor command:
  4330.  
  4331.          command := SET var BECOMES
  4332.                         ( expr
  4333.                         | QUOTE QUOTE
  4334.                         | QUOTE expr QUOTE
  4335.                         | QUOTE command QUOTE
  4336.                         )
  4337.  
  4338. The definition of expr uses left recursion which must be eliminated
  4339. when using Antlr:
  4340.  
  4341.          op      := AddOp
  4342.                  |  MulOp
  4343.  
  4344.          expr    := QUOTE anyCharButQuote QUOTE (op expr)*
  4345.  
  4346. Since expr begins with QUOTE and all the alternatives of the sub-rule
  4347. of command also start with QUOTE this too can be left-factored:
  4348.  
  4349.          command := SET var BECOMES QUOTE
  4350.                         ( expr_suffix
  4351.                         | QUOTE
  4352.                         | expr QUOTE
  4353.                         | command QUOTE
  4354.                         )
  4355.  
  4356.          expr_suffix := anyCharButQuote QUOTE   (op expr)*
  4357.          expr        := QUOTE expr_suffix
  4358.  
  4359. The final grammar can be built by Antlr with k=2.
  4360.  
  4361.                                                                        Page 87
  4362. #header <<#include "charbuf.h">>
  4363.  
  4364. <<
  4365. int main() {
  4366.         ANTLR(repeat(),stdin);
  4367.         return 0;
  4368. }
  4369. >>
  4370. #token Q        "\""
  4371. #token SVB      "svb"
  4372. #token Qbar     "[a-z A-Z]*"
  4373. #token AddOp    "\+"
  4374. #token MulOp    "\*"
  4375. #token WS       "\ "    <<zzskip();>>
  4376. #token NL       "\n"    <<zzskip();>>
  4377.  
  4378. repeat      : ( command )+ "@";
  4379. command     : SVB Q ( expr_suffix
  4380.                     | expr Q
  4381.                     | Q          <<printf("null command\n");>>
  4382.  
  4383.                     | command Q  <<printf("command\n");>>
  4384.                     );
  4385.  
  4386. expr_suffix : Qbar Q <<printf("The Qbar expr is (%s)\n",$1.text);>>
  4387.                  { op expr };
  4388. expr        : Q expr_suffix;
  4389. op          : AddOp | MulOp ;
  4390. -------------------------------------------------------------------------------
  4391.